[libcxx-commits] [libcxx] [libc++] Implement P1901R2: owner_hash and owner_equal for shared_ptr/weak_ptr (PR #210551)

Avi Patel via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jul 26 12:18:05 PDT 2026


https://github.com/firedog1234 updated https://github.com/llvm/llvm-project/pull/210551

>From a1178273ee760811d06d3f7a0cdb2a95ba3d4183 Mon Sep 17 00:00:00 2001
From: avipatel <aviipatel06 at gmail.com>
Date: Sat, 18 Jul 2026 15:26:56 -0400
Subject: [PATCH 1/4] [libc++] Implement P1901R2: owner_hash and owner_equal
 for shared_ptr/weak_ptr

---
 libcxx/docs/FeatureTestMacroTable.rst         |  2 +-
 libcxx/docs/ReleaseNotes/23.rst               |  1 +
 libcxx/docs/Status/Cxx26Papers.csv            |  2 +-
 libcxx/include/__memory/shared_ptr.h          | 71 +++++++++++++++++++
 libcxx/include/memory                         | 32 +++++++++
 libcxx/include/version                        |  2 +-
 .../memory.version.compile.pass.cpp           | 16 ++---
 .../version.version.compile.pass.cpp          | 16 ++---
 .../owner_equal_shared_ptr.pass.cpp           | 40 +++++++++++
 .../owner_equal_weak_ptr.pass.cpp             | 41 +++++++++++
 .../owner_hash.pass.cpp                       | 44 ++++++++++++
 .../owner_equal.pass.cpp                      | 69 ++++++++++++++++++
 .../owner_hash.pass.cpp                       | 49 +++++++++++++
 .../owner_equal_shared_ptr.pass.cpp           | 37 ++++++++++
 .../owner_equal_weak_ptr.pass.cpp             | 42 +++++++++++
 .../owner_hash.pass.cpp                       | 34 +++++++++
 .../generate_feature_test_macro_components.py |  1 -
 17 files changed, 473 insertions(+), 26 deletions(-)
 create mode 100644 libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_shared_ptr.pass.cpp
 create mode 100644 libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_weak_ptr.pass.cpp
 create mode 100644 libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_hash.pass.cpp
 create mode 100644 libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp
 create mode 100644 libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp
 create mode 100644 libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_shared_ptr.pass.cpp
 create mode 100644 libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_weak_ptr.pass.cpp
 create mode 100644 libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_hash.pass.cpp

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 6bf2f35fb4212..8a26828240de4 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -526,7 +526,7 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_senders``                                      *unimplemented*
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_smart_ptr_owner_equality``                     *unimplemented*
+    ``__cpp_lib_smart_ptr_owner_equality``                     ``202306L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_span_at``                                      ``202311L``
     ---------------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index 1213e8f43c8cd..1dee9843c9c55 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -55,6 +55,7 @@ Implemented Papers
 - P3369R0: constexpr for ``uninitialized_default_construct`` (`Github <https://llvm.org/PR118380>`__)
 - P3508R0: Wording for "constexpr for specialized memory algorithms" (`Github <https://llvm.org/PR118379>`__)
 - P4206R0: Revert string support in ``std::constant_wrapper`` (`Github <https://llvm.org/PR203338>`__)
+- P1901R2: Enabling the Use of ``weak_ptr`` as Keys in Unordered Associative Containers (`Github <https://llvm.org/PR105372>`__)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index efc98495d1d5c..98135f198110c 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -12,7 +12,7 @@
 "`P2338R4 <https://wg21.link/P2338R4>`__","Freestanding Library: Character primitives and the C library","2023-06 (Varna)","","","`#105369 <https://github.com/llvm/llvm-project/issues/105369>`__",""
 "`P2013R5 <https://wg21.link/P2013R5>`__","Freestanding Language: Optional ``::operator new``","2023-06 (Varna)","","","`#105370 <https://github.com/llvm/llvm-project/issues/105370>`__",""
 "`P2363R5 <https://wg21.link/P2363R5>`__","Extending associative containers with the remaining heterogeneous overloads","2023-06 (Varna)","","","`#105371 <https://github.com/llvm/llvm-project/issues/105371>`__",""
-"`P1901R2 <https://wg21.link/P1901R2>`__","Enabling the Use of ``weak_ptr`` as Keys in Unordered Associative Containers","2023-06 (Varna)","","","`#105372 <https://github.com/llvm/llvm-project/issues/105372>`__",""
+"`P1901R2 <https://wg21.link/P1901R2>`__","Enabling the Use of ``weak_ptr`` as Keys in Unordered Associative Containers","2023-06 (Varna)","|Complete|","23","`#105372 <https://github.com/llvm/llvm-project/issues/105372>`__",""
 "`P1885R12 <https://wg21.link/P1885R12>`__","Naming Text Encodings to Demystify Them","2023-06 (Varna)","|Complete|","23","`#105373 <https://github.com/llvm/llvm-project/issues/105373>`__",""
 "`P0792R14 <https://wg21.link/P0792R14>`__","``function_ref``: a type-erased callable reference","2023-06 (Varna)","","","`#105376 <https://github.com/llvm/llvm-project/issues/105376>`__",""
 "`P2874R2 <https://wg21.link/P2874R2>`__","P2874R2: Mandating Annex D Require No More","2023-06 (Varna)","|Complete|","12","`#105377 <https://github.com/llvm/llvm-project/issues/105377>`__",""
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index ebd542ba14d01..0770f2a8e383d 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -18,6 +18,7 @@
 #include <__cstddef/ptrdiff_t.h>
 #include <__exception/exception.h>
 #include <__functional/binary_function.h>
+#include <__functional/hash.h>
 #include <__functional/operations.h>
 #include <__functional/reference_wrapper.h>
 #include <__fwd/ostream.h>
@@ -555,6 +556,22 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
 
   _LIBCPP_HIDE_FROM_ABI bool __owner_equivalent(const shared_ptr& __p) const { return __cntrl_ == __p.__cntrl_; }
 
+#if _LIBCPP_STD_VER >= 26
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t owner_hash() const _NOEXCEPT {
+    return std::hash<__shared_weak_count*>()(__cntrl_);
+  }
+
+  template <class _Up>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(shared_ptr<_Up> const& __p) const _NOEXCEPT {
+    return __cntrl_ == __p.__cntrl_;
+  }
+
+  template <class _Up>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(weak_ptr<_Up> const& __p) const _NOEXCEPT {
+    return __cntrl_ == __p.__cntrl_;
+  }
+#endif
+
 #if _LIBCPP_STD_VER >= 17
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const {
     static_assert(is_array<_Tp>::value, "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
@@ -1244,6 +1261,22 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr {
     return __cntrl_ < __r.__cntrl_;
   }
 
+#if _LIBCPP_STD_VER >= 26
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t owner_hash() const _NOEXCEPT {
+    return std::hash<__shared_weak_count*>()(__cntrl_);
+  }
+
+  template <class _Up>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(shared_ptr<_Up> const& __p) const _NOEXCEPT {
+    return __cntrl_ == __p.__cntrl_;
+  }
+
+  template <class _Up>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(weak_ptr<_Up> const& __p) const _NOEXCEPT {
+    return __cntrl_ == __p.__cntrl_;
+  }
+#endif
+
   template <class _Up>
   friend class weak_ptr;
   template <class _Up>
@@ -1317,6 +1350,44 @@ struct owner_less<void> {
 };
 #endif
 
+#if _LIBCPP_STD_VER >= 26
+struct owner_hash {
+  template <class _Tp>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(shared_ptr<_Tp> const& __p) const _NOEXCEPT {
+    return __p.owner_hash();
+  }
+  template <class _Tp>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(weak_ptr<_Tp> const& __p) const _NOEXCEPT {
+    return __p.owner_hash();
+  }
+  typedef void is_transparent;
+};
+
+struct owner_equal {
+  template <class _Tp, class _Up>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool
+  operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT {
+    return __x.owner_equal(__y);
+  }
+  template <class _Tp, class _Up>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool
+  operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT {
+    return __x.owner_equal(__y);
+  }
+  template <class _Tp, class _Up>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool
+  operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT {
+    return __x.owner_equal(__y);
+  }
+  template <class _Tp, class _Up>
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool
+  operator()(weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT {
+    return __x.owner_equal(__y);
+  }
+  typedef void is_transparent;
+};
+#endif
+
 template <class _Tp>
 class enable_shared_from_this {
   mutable weak_ptr<_Tp> __weak_this_;
diff --git a/libcxx/include/memory b/libcxx/include/memory
index d5d48ed9a9e6d..03636ddb839b0 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -633,6 +633,9 @@ public:
     explicit operator bool() const noexcept;
     template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
     template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
+    size_t owner_hash() const noexcept;                                       // C++26
+    template<class U> bool owner_equal(shared_ptr<U> const& b) const noexcept; // C++26
+    template<class U> bool owner_equal(weak_ptr<U> const& b) const noexcept;   // C++26
 };
 
 template<class T>
@@ -771,6 +774,9 @@ public:
     shared_ptr<T> lock() const noexcept;
     template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
     template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
+    size_t owner_hash() const noexcept;                                       // C++26
+    template<class U> bool owner_equal(shared_ptr<U> const& b) const noexcept; // C++26
+    template<class U> bool owner_equal(weak_ptr<U> const& b) const noexcept;   // C++26
 };
 
 template<class T>
@@ -817,6 +823,32 @@ struct owner_less<void>
     typedef void is_transparent;
 };
 
+// class owner_hash:                                                          // C++26
+struct owner_hash
+{
+    template <class _Tp>
+    size_t operator()(shared_ptr<_Tp> const& __p) const noexcept;
+    template <class _Tp>
+    size_t operator()(weak_ptr<_Tp> const& __p) const noexcept;
+
+    typedef void is_transparent;
+};
+
+// class owner_equal:                                                         // C++26
+struct owner_equal
+{
+    template <class _Tp, class _Up>
+    bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
+    template <class _Tp, class _Up>
+    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
+    template <class _Tp, class _Up>
+    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
+    template <class _Tp, class _Up>
+    bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
+
+    typedef void is_transparent;
+};
+
 template<class T>
 class enable_shared_from_this
 {
diff --git a/libcxx/include/version b/libcxx/include/version
index 4a6b01093641d..31b5cc4048e18 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -628,7 +628,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_reference_wrapper                    202403L
 # define __cpp_lib_saturation_arithmetic                202603L
 // # define __cpp_lib_senders                              202406L
-// # define __cpp_lib_smart_ptr_owner_equality             202306L
+# define __cpp_lib_smart_ptr_owner_equality             202306L
 # define __cpp_lib_span_at                              202311L
 # define __cpp_lib_sstream_from_string_view             202306L
 # define __cpp_lib_string_subview                       202506L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index c58357a463ffd..dc14ff766ac5c 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -648,17 +648,11 @@
 #    error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++26"
 #  endif
 
-#  if !defined(_LIBCPP_VERSION)
-#    ifndef __cpp_lib_smart_ptr_owner_equality
-#      error "__cpp_lib_smart_ptr_owner_equality should be defined in c++26"
-#    endif
-#    if __cpp_lib_smart_ptr_owner_equality != 202306L
-#      error "__cpp_lib_smart_ptr_owner_equality should have the value 202306L in c++26"
-#    endif
-#  else
-#    ifdef __cpp_lib_smart_ptr_owner_equality
-#      error "__cpp_lib_smart_ptr_owner_equality should not be defined because it is unimplemented in libc++!"
-#    endif
+#  ifndef __cpp_lib_smart_ptr_owner_equality
+#    error "__cpp_lib_smart_ptr_owner_equality should be defined in c++26"
+#  endif
+#  if __cpp_lib_smart_ptr_owner_equality != 202306L
+#    error "__cpp_lib_smart_ptr_owner_equality should have the value 202306L in c++26"
 #  endif
 
 #  ifndef __cpp_lib_to_address
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index f2d74cc99d864..11b181a66c518 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -8024,17 +8024,11 @@
 #    error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++26"
 #  endif
 
-#  if !defined(_LIBCPP_VERSION)
-#    ifndef __cpp_lib_smart_ptr_owner_equality
-#      error "__cpp_lib_smart_ptr_owner_equality should be defined in c++26"
-#    endif
-#    if __cpp_lib_smart_ptr_owner_equality != 202306L
-#      error "__cpp_lib_smart_ptr_owner_equality should have the value 202306L in c++26"
-#    endif
-#  else
-#    ifdef __cpp_lib_smart_ptr_owner_equality
-#      error "__cpp_lib_smart_ptr_owner_equality should not be defined because it is unimplemented in libc++!"
-#    endif
+#  ifndef __cpp_lib_smart_ptr_owner_equality
+#    error "__cpp_lib_smart_ptr_owner_equality should be defined in c++26"
+#  endif
+#  if __cpp_lib_smart_ptr_owner_equality != 202306L
+#    error "__cpp_lib_smart_ptr_owner_equality should have the value 202306L in c++26"
 #  endif
 
 #  ifndef __cpp_lib_source_location
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_shared_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_shared_ptr.pass.cpp
new file mode 100644
index 0000000000000..0f8c6935ef811
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_shared_ptr.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <memory>
+
+// shared_ptr
+
+// template<class U> bool owner_equal(shared_ptr<U> const& b) const noexcept;
+
+#include <memory>
+#include <cassert>
+#include "test_macros.h"
+
+int main(int, char**) {
+  const std::shared_ptr<int> p1(new int);
+  const std::shared_ptr<int> p2 = p1;
+  const std::shared_ptr<int> p3(new int);
+  const std::shared_ptr<void> empty1;
+  const std::shared_ptr<long> empty2;
+
+  assert(p1.owner_equal(p2));
+  assert(p2.owner_equal(p1));
+  assert(!p1.owner_equal(p3));
+  assert(!p3.owner_equal(p1));
+
+  assert(empty1.owner_equal(empty2));
+  assert(!p1.owner_equal(empty1));
+
+  ASSERT_SAME_TYPE(decltype(p1.owner_equal(p2)), bool);
+  ASSERT_NOEXCEPT(p1.owner_equal(p2));
+
+  return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_weak_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_weak_ptr.pass.cpp
new file mode 100644
index 0000000000000..6ac9f57e07a05
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_weak_ptr.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <memory>
+
+// shared_ptr
+
+// template<class U> bool owner_equal(weak_ptr<U> const& b) const noexcept;
+
+#include <memory>
+#include <cassert>
+#include "test_macros.h"
+
+int main(int, char**) {
+  const std::shared_ptr<int> p1(new int);
+  const std::shared_ptr<int> p2 = p1;
+  const std::shared_ptr<int> p3(new int);
+  const std::weak_ptr<int> w1(p1);
+  const std::weak_ptr<int> w3(p3);
+  const std::shared_ptr<void> empty_sp;
+  const std::weak_ptr<long> empty_wp;
+
+  assert(p1.owner_equal(w1));
+  assert(p2.owner_equal(w1));
+  assert(!p1.owner_equal(w3));
+  assert(!p3.owner_equal(w1));
+
+  assert(empty_sp.owner_equal(empty_wp));
+
+  ASSERT_SAME_TYPE(decltype(p1.owner_equal(w1)), bool);
+  ASSERT_NOEXCEPT(p1.owner_equal(w1));
+
+  return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_hash.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_hash.pass.cpp
new file mode 100644
index 0000000000000..57967b9369fe3
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_hash.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <memory>
+
+// shared_ptr
+
+// size_t owner_hash() const noexcept;
+
+#include <memory>
+#include <cassert>
+#include <cstddef>
+#include "test_macros.h"
+
+struct Pair {
+  int a;
+  int b;
+};
+
+int main(int, char**) {
+  const std::shared_ptr<int> p1(new int);
+  const std::shared_ptr<int> p2 = p1;
+  const std::weak_ptr<int> w1(p1);
+
+  assert(p1.owner_hash() == p2.owner_hash());
+  assert(p1.owner_hash() == w1.owner_hash());
+
+  const std::shared_ptr<Pair> sp(new Pair{1, 2});
+  const std::shared_ptr<int> alias(sp, &sp->b);
+  assert(static_cast<void*>(sp.get()) != static_cast<void*>(alias.get()));
+  assert(sp.owner_hash() == alias.owner_hash());
+
+  ASSERT_SAME_TYPE(decltype(p1.owner_hash()), std::size_t);
+  ASSERT_NOEXCEPT(p1.owner_hash());
+
+  return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp
new file mode 100644
index 0000000000000..1c6c9e8bd5d67
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <memory>
+
+// struct owner_equal
+// {
+//     template<class T, class U>
+//         bool operator()(shared_ptr<T> const&, shared_ptr<U> const&) const noexcept;
+//     template<class T, class U>
+//         bool operator()(shared_ptr<T> const&, weak_ptr<U> const&) const noexcept;
+//     template<class T, class U>
+//         bool operator()(weak_ptr<T> const&, shared_ptr<U> const&) const noexcept;
+//     template<class T, class U>
+//         bool operator()(weak_ptr<T> const&, weak_ptr<U> const&) const noexcept;
+//
+//     typedef unspecified is_transparent;
+// };
+
+#include <memory>
+#include <cassert>
+#include <type_traits>
+#include <unordered_set>
+#include "test_macros.h"
+
+int main(int, char**) {
+  const std::shared_ptr<int> p1(new int);
+  const std::shared_ptr<int> p2 = p1;
+  const std::shared_ptr<int> p3(new int);
+  const std::weak_ptr<int> w1(p1);
+  const std::weak_ptr<int> w3(p3);
+
+  std::owner_equal oe;
+
+  assert(oe(p1, p2));
+  assert(oe(p1, w1));
+  assert(oe(w1, p1));
+  assert(oe(w1, w1));
+
+  assert(!oe(p1, p3));
+  assert(!oe(p1, w3));
+  assert(!oe(w1, p3));
+  assert(!oe(w1, w3));
+
+  ASSERT_SAME_TYPE(decltype(oe(p1, p2)), bool);
+  ASSERT_NOEXCEPT(oe(p1, p2));
+  ASSERT_NOEXCEPT(oe(p1, w1));
+  ASSERT_NOEXCEPT(oe(w1, p1));
+  ASSERT_NOEXCEPT(oe(w1, w1));
+
+  static_assert(std::is_same<std::owner_equal::is_transparent, void>::value, "");
+
+  {
+    std::unordered_set<std::weak_ptr<int>, std::owner_hash, std::owner_equal> s;
+    s.insert(w1);
+    assert(s.count(w1) == 1);
+    assert(s.count(std::weak_ptr<int>(p2)) == 1);
+    assert(s.count(w3) == 0);
+  }
+
+  return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp
new file mode 100644
index 0000000000000..0aaa622246023
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <memory>
+
+// struct owner_hash
+// {
+//     template<class T>
+//         size_t operator()(shared_ptr<T> const&) const noexcept;
+//     template<class T>
+//         size_t operator()(weak_ptr<T> const&) const noexcept;
+//
+//     typedef unspecified is_transparent;
+// };
+
+#include <memory>
+#include <cassert>
+#include <type_traits>
+#include "test_macros.h"
+
+int main(int, char**) {
+  const std::shared_ptr<int> p1(new int);
+  const std::shared_ptr<int> p2 = p1;
+  const std::weak_ptr<int> w1(p1);
+
+  std::owner_hash oh;
+
+  assert(oh(p1) == p1.owner_hash());
+  assert(oh(w1) == w1.owner_hash());
+
+  assert(oh(p1) == oh(p2));
+  assert(oh(p1) == oh(w1));
+
+  ASSERT_SAME_TYPE(decltype(oh(p1)), std::size_t);
+  ASSERT_SAME_TYPE(decltype(oh(w1)), std::size_t);
+  ASSERT_NOEXCEPT(oh(p1));
+  ASSERT_NOEXCEPT(oh(w1));
+
+  static_assert(std::is_same<std::owner_hash::is_transparent, void>::value, "");
+
+  return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_shared_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_shared_ptr.pass.cpp
new file mode 100644
index 0000000000000..35c97a72c8c3c
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_shared_ptr.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <memory>
+
+// weak_ptr
+
+// template<class U> bool owner_equal(shared_ptr<U> const& b) const noexcept;
+
+#include <memory>
+#include <cassert>
+#include "test_macros.h"
+
+int main(int, char**) {
+  const std::shared_ptr<int> p1(new int);
+  const std::shared_ptr<int> p3(new int);
+  const std::weak_ptr<int> w1(p1);
+  const std::weak_ptr<void> empty;
+
+  assert(w1.owner_equal(p1));
+  assert(!w1.owner_equal(p3));
+
+  const std::shared_ptr<long> empty_sp;
+  assert(empty.owner_equal(empty_sp));
+
+  ASSERT_SAME_TYPE(decltype(w1.owner_equal(p1)), bool);
+  ASSERT_NOEXCEPT(w1.owner_equal(p1));
+
+  return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_weak_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_weak_ptr.pass.cpp
new file mode 100644
index 0000000000000..bfd4628edd364
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_weak_ptr.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <memory>
+
+// weak_ptr
+
+// template<class U> bool owner_equal(weak_ptr<U> const& b) const noexcept;
+
+#include <memory>
+#include <cassert>
+#include "test_macros.h"
+
+int main(int, char**) {
+  const std::shared_ptr<int> p1(new int);
+  const std::shared_ptr<int> p3(new int);
+  const std::weak_ptr<int> w1(p1);
+  const std::weak_ptr<int> w2(p1);
+  const std::weak_ptr<int> w3(p3);
+  const std::weak_ptr<void> empty1;
+  const std::weak_ptr<long> empty2;
+
+  assert(w1.owner_equal(w2));
+  assert(w2.owner_equal(w1));
+  assert(!w1.owner_equal(w3));
+  assert(!w3.owner_equal(w1));
+
+  assert(empty1.owner_equal(empty2));
+  assert(!w1.owner_equal(empty1));
+
+  ASSERT_SAME_TYPE(decltype(w1.owner_equal(w2)), bool);
+  ASSERT_NOEXCEPT(w1.owner_equal(w2));
+
+  return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_hash.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_hash.pass.cpp
new file mode 100644
index 0000000000000..772344f1b05de
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_hash.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <memory>
+
+// weak_ptr
+
+// size_t owner_hash() const noexcept;
+
+#include <memory>
+#include <cassert>
+#include <cstddef>
+#include "test_macros.h"
+
+int main(int, char**) {
+  const std::shared_ptr<int> p1(new int);
+  const std::weak_ptr<int> w1(p1);
+  const std::weak_ptr<int> w2(p1);
+
+  assert(w1.owner_hash() == w2.owner_hash());
+  assert(w1.owner_hash() == p1.owner_hash());
+
+  ASSERT_SAME_TYPE(decltype(w1.owner_hash()), std::size_t);
+  ASSERT_NOEXCEPT(w1.owner_hash());
+
+  return 0;
+}
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index f4e16078d5af0..56726e485493e 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1316,7 +1316,6 @@ def add_version_header(tc):
                 "c++26": 202306  # P1901R2 Enabling the Use of weak_ptr as Keys in Unordered Associative Containers
             },
             "headers": ["memory"],
-            "unimplemented": True,
         },
         {
             "name": "__cpp_lib_source_location",

>From fbb70af7075ed548b3d8c31bbf033f0d2d548082 Mon Sep 17 00:00:00 2001
From: avipatel <aviipatel06 at gmail.com>
Date: Sun, 26 Jul 2026 01:22:32 -0400
Subject: [PATCH 2/4] update: address review feedback

---
 libcxx/docs/ReleaseNotes/23.rst               |  1 -
 libcxx/docs/ReleaseNotes/24.rst               |  1 +
 libcxx/docs/Status/Cxx26Papers.csv            |  2 +-
 libcxx/include/__memory/shared_ptr.h          | 38 +++++++++--------
 libcxx/include/memory                         | 41 +++++++++----------
 libcxx/modules/std/memory.inc                 |  8 ++++
 .../utilities/smartptr/nodiscard.verify.cpp   | 32 +++++++++++++++
 .../owner_equal_shared_ptr.pass.cpp           | 14 ++++---
 .../owner_equal_weak_ptr.pass.cpp             | 14 ++++---
 .../owner_hash.pass.cpp                       | 16 ++++----
 .../owner_equal.pass.cpp                      | 25 +++++------
 .../owner_hash.pass.cpp                       | 27 ++++++------
 .../owner_equal_shared_ptr.pass.cpp           | 14 ++++---
 .../owner_equal_weak_ptr.pass.cpp             | 14 ++++---
 .../owner_hash.pass.cpp                       | 14 ++++---
 15 files changed, 158 insertions(+), 103 deletions(-)

diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index 6bbf4d3dbb87c..f7a8e5b04f1ea 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -55,7 +55,6 @@ Implemented Papers
 - P3369R0: constexpr for ``uninitialized_default_construct`` (`Github <https://llvm.org/PR118380>`__)
 - P3508R0: Wording for "constexpr for specialized memory algorithms" (`Github <https://llvm.org/PR118379>`__)
 - P4206R0: Revert string support in ``std::constant_wrapper`` (`Github <https://llvm.org/PR203338>`__)
-- P1901R2: Enabling the Use of ``weak_ptr`` as Keys in Unordered Associative Containers (`Github <https://llvm.org/PR105372>`__)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/ReleaseNotes/24.rst b/libcxx/docs/ReleaseNotes/24.rst
index 70c704ff9d326..2cd6c83713fe1 100644
--- a/libcxx/docs/ReleaseNotes/24.rst
+++ b/libcxx/docs/ReleaseNotes/24.rst
@@ -39,6 +39,7 @@ Implemented Papers
 ------------------
 
 - P0493R5: Atomic minimum/maximum (`Github <https://llvm.org/PR105418>`__)
+- P1901R2: Enabling the Use of ``weak_ptr`` as Keys in Unordered Associative Containers (`Github <https://llvm.org/PR105372>`__)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/Status/Cxx26Papers.csv b/libcxx/docs/Status/Cxx26Papers.csv
index 22575a5c1a6e6..af1894fb310a6 100644
--- a/libcxx/docs/Status/Cxx26Papers.csv
+++ b/libcxx/docs/Status/Cxx26Papers.csv
@@ -12,7 +12,7 @@
 "`P2338R4 <https://wg21.link/P2338R4>`__","Freestanding Library: Character primitives and the C library","2023-06 (Varna)","","","`#105369 <https://github.com/llvm/llvm-project/issues/105369>`__",""
 "`P2013R5 <https://wg21.link/P2013R5>`__","Freestanding Language: Optional ``::operator new``","2023-06 (Varna)","","","`#105370 <https://github.com/llvm/llvm-project/issues/105370>`__",""
 "`P2363R5 <https://wg21.link/P2363R5>`__","Extending associative containers with the remaining heterogeneous overloads","2023-06 (Varna)","","","`#105371 <https://github.com/llvm/llvm-project/issues/105371>`__",""
-"`P1901R2 <https://wg21.link/P1901R2>`__","Enabling the Use of ``weak_ptr`` as Keys in Unordered Associative Containers","2023-06 (Varna)","|Complete|","23","`#105372 <https://github.com/llvm/llvm-project/issues/105372>`__",""
+"`P1901R2 <https://wg21.link/P1901R2>`__","Enabling the Use of ``weak_ptr`` as Keys in Unordered Associative Containers","2023-06 (Varna)","|Complete|","24","`#105372 <https://github.com/llvm/llvm-project/issues/105372>`__",""
 "`P1885R12 <https://wg21.link/P1885R12>`__","Naming Text Encodings to Demystify Them","2023-06 (Varna)","|Complete|","23","`#105373 <https://github.com/llvm/llvm-project/issues/105373>`__",""
 "`P0792R14 <https://wg21.link/P0792R14>`__","``function_ref``: a type-erased callable reference","2023-06 (Varna)","","","`#105376 <https://github.com/llvm/llvm-project/issues/105376>`__",""
 "`P2874R2 <https://wg21.link/P2874R2>`__","P2874R2: Mandating Annex D Require No More","2023-06 (Varna)","|Complete|","12","`#105377 <https://github.com/llvm/llvm-project/issues/105377>`__",""
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 9ab60d5996476..7d8a0d27739a0 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -557,17 +557,17 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
   _LIBCPP_HIDE_FROM_ABI bool __owner_equivalent(const shared_ptr& __p) const { return __cntrl_ == __p.__cntrl_; }
 
 #if _LIBCPP_STD_VER >= 26
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t owner_hash() const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t owner_hash() const noexcept {
     return std::hash<__shared_weak_count*>()(__cntrl_);
   }
 
   template <class _Up>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(shared_ptr<_Up> const& __p) const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(shared_ptr<_Up> const& __p) const noexcept {
     return __cntrl_ == __p.__cntrl_;
   }
 
   template <class _Up>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(weak_ptr<_Up> const& __p) const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(weak_ptr<_Up> const& __p) const noexcept {
     return __cntrl_ == __p.__cntrl_;
   }
 #endif
@@ -1263,17 +1263,17 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr {
   }
 
 #if _LIBCPP_STD_VER >= 26
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t owner_hash() const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t owner_hash() const noexcept {
     return std::hash<__shared_weak_count*>()(__cntrl_);
   }
 
   template <class _Up>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(shared_ptr<_Up> const& __p) const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(shared_ptr<_Up> const& __p) const noexcept {
     return __cntrl_ == __p.__cntrl_;
   }
 
   template <class _Up>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(weak_ptr<_Up> const& __p) const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(weak_ptr<_Up> const& __p) const noexcept {
     return __cntrl_ == __p.__cntrl_;
   }
 #endif
@@ -1354,38 +1354,40 @@ struct owner_less<void> {
 #if _LIBCPP_STD_VER >= 26
 struct owner_hash {
   template <class _Tp>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(shared_ptr<_Tp> const& __p) const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(shared_ptr<_Tp> const& __p) const noexcept {
     return __p.owner_hash();
   }
   template <class _Tp>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(weak_ptr<_Tp> const& __p) const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(weak_ptr<_Tp> const& __p) const noexcept {
     return __p.owner_hash();
   }
-  typedef void is_transparent;
+
+  using is_transparent = void;
 };
 
 struct owner_equal {
   template <class _Tp, class _Up>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool
-  operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
+  operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept {
     return __x.owner_equal(__y);
   }
   template <class _Tp, class _Up>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool
-  operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
+  operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept {
     return __x.owner_equal(__y);
   }
   template <class _Tp, class _Up>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool
-  operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
+  operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept {
     return __x.owner_equal(__y);
   }
   template <class _Tp, class _Up>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool
-  operator()(weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
+  operator()(weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept {
     return __x.owner_equal(__y);
   }
-  typedef void is_transparent;
+
+  using is_transparent = void;
 };
 #endif
 
diff --git a/libcxx/include/memory b/libcxx/include/memory
index 03636ddb839b0..2c8340aa05082 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -633,7 +633,7 @@ public:
     explicit operator bool() const noexcept;
     template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
     template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
-    size_t owner_hash() const noexcept;                                       // C++26
+    size_t owner_hash() const noexcept;                                        // C++26
     template<class U> bool owner_equal(shared_ptr<U> const& b) const noexcept; // C++26
     template<class U> bool owner_equal(weak_ptr<U> const& b) const noexcept;   // C++26
 };
@@ -774,7 +774,7 @@ public:
     shared_ptr<T> lock() const noexcept;
     template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
     template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
-    size_t owner_hash() const noexcept;                                       // C++26
+    size_t owner_hash() const noexcept;                                        // C++26
     template<class U> bool owner_equal(shared_ptr<U> const& b) const noexcept; // C++26
     template<class U> bool owner_equal(weak_ptr<U> const& b) const noexcept;   // C++26
 };
@@ -824,29 +824,28 @@ struct owner_less<void>
 };
 
 // class owner_hash:                                                          // C++26
-struct owner_hash
-{
-    template <class _Tp>
-    size_t operator()(shared_ptr<_Tp> const& __p) const noexcept;
-    template <class _Tp>
-    size_t operator()(weak_ptr<_Tp> const& __p) const noexcept;
+struct owner_hash {
+  template<class T>
+    size_t operator()(const shared_ptr<T>&) const noexcept;
 
-    typedef void is_transparent;
+  template<class T>
+    size_t operator()(const weak_ptr<T>&) const noexcept;
+
+  using is_transparent = unspecified;
 };
 
 // class owner_equal:                                                         // C++26
-struct owner_equal
-{
-    template <class _Tp, class _Up>
-    bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
-    template <class _Tp, class _Up>
-    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
-    template <class _Tp, class _Up>
-    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
-    template <class _Tp, class _Up>
-    bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
-
-    typedef void is_transparent;
+struct owner_equal {
+  template<class T, class U>
+    bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
+  template<class T, class U>
+    bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
+  template<class T, class U>
+    bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
+  template<class T, class U>
+    bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
+
+  using is_transparent = unspecified;
 };
 
 template<class T>
diff --git a/libcxx/modules/std/memory.inc b/libcxx/modules/std/memory.inc
index c25e9e3443e9c..0338ec0db325e 100644
--- a/libcxx/modules/std/memory.inc
+++ b/libcxx/modules/std/memory.inc
@@ -171,6 +171,14 @@ export namespace std {
   // [util.smartptr.ownerless], class template owner_less
   using std::owner_less;
 
+#if _LIBCPP_STD_VER >= 26
+  // [util.smartptr.owner.hash], class owner_hash
+  using std::owner_hash;
+
+  // [util.smartptr.owner.equal], class owner_equal
+  using std::owner_equal;
+#endif
+
   // [util.smartptr.enab], class template enable_shared_from_this
   using std::enable_shared_from_this;
 
diff --git a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
index 6943a4002c245..84020942f0a74 100644
--- a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
@@ -59,6 +59,14 @@ void test() {
     sPtr.owner_before(std::shared_ptr<int>());
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     sPtr.owner_before(std::weak_ptr<int>());
+#if TEST_STD_VER >= 26
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    sPtr.owner_hash();
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    sPtr.owner_equal(std::shared_ptr<int>());
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    sPtr.owner_equal(std::weak_ptr<int>());
+#endif
 #if TEST_STD_VER >= 17
     sPtr[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
 #endif
@@ -138,7 +146,31 @@ void test() {
     wPtr.owner_before(std::weak_ptr<int>());
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     wPtr.owner_before(std::shared_ptr<int>());
+#if TEST_STD_VER >= 26
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    wPtr.owner_hash();
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    wPtr.owner_equal(std::weak_ptr<int>());
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    wPtr.owner_equal(std::shared_ptr<int>());
+#endif
+  }
+#if TEST_STD_VER >= 26
+  { // [util.smartptr.owner.hash], [util.smartptr.owner.equal]
+    std::shared_ptr<int> sPtr;
+    std::weak_ptr<int> wPtr;
+
+    std::owner_hash oh;
+    oh(sPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    oh(wPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+    std::owner_equal oe;
+    oe(sPtr, sPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    oe(sPtr, wPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    oe(wPtr, sPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    oe(wPtr, wPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   }
+#endif
   { // [util.smartptr.enab]
     class EnableShared : public std::enable_shared_from_this<EnableShared> {};
     EnableShared es;
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_shared_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_shared_ptr.pass.cpp
index 0f8c6935ef811..356ad0ab48275 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_shared_ptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_shared_ptr.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <memory>
 
@@ -14,8 +14,10 @@
 
 // template<class U> bool owner_equal(shared_ptr<U> const& b) const noexcept;
 
-#include <memory>
 #include <cassert>
+#include <concepts>
+#include <memory>
+
 #include "test_macros.h"
 
 int main(int, char**) {
@@ -25,7 +27,10 @@ int main(int, char**) {
   const std::shared_ptr<void> empty1;
   const std::shared_ptr<long> empty2;
 
-  assert(p1.owner_equal(p2));
+  std::same_as<bool> decltype(auto) result = p1.owner_equal(p2);
+  assert(result);
+  static_assert(noexcept(p1.owner_equal(p2)));
+
   assert(p2.owner_equal(p1));
   assert(!p1.owner_equal(p3));
   assert(!p3.owner_equal(p1));
@@ -33,8 +38,5 @@ int main(int, char**) {
   assert(empty1.owner_equal(empty2));
   assert(!p1.owner_equal(empty1));
 
-  ASSERT_SAME_TYPE(decltype(p1.owner_equal(p2)), bool);
-  ASSERT_NOEXCEPT(p1.owner_equal(p2));
-
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_weak_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_weak_ptr.pass.cpp
index 6ac9f57e07a05..11166b2bec49d 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_weak_ptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_equal_weak_ptr.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <memory>
 
@@ -14,8 +14,10 @@
 
 // template<class U> bool owner_equal(weak_ptr<U> const& b) const noexcept;
 
-#include <memory>
 #include <cassert>
+#include <concepts>
+#include <memory>
+
 #include "test_macros.h"
 
 int main(int, char**) {
@@ -27,15 +29,15 @@ int main(int, char**) {
   const std::shared_ptr<void> empty_sp;
   const std::weak_ptr<long> empty_wp;
 
-  assert(p1.owner_equal(w1));
+  std::same_as<bool> decltype(auto) result = p1.owner_equal(w1);
+  assert(result);
+  static_assert(noexcept(p1.owner_equal(w1)));
+
   assert(p2.owner_equal(w1));
   assert(!p1.owner_equal(w3));
   assert(!p3.owner_equal(w1));
 
   assert(empty_sp.owner_equal(empty_wp));
 
-  ASSERT_SAME_TYPE(decltype(p1.owner_equal(w1)), bool);
-  ASSERT_NOEXCEPT(p1.owner_equal(w1));
-
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_hash.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_hash.pass.cpp
index 57967b9369fe3..79ebea344ba74 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_hash.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/owner_hash.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <memory>
 
@@ -14,9 +14,11 @@
 
 // size_t owner_hash() const noexcept;
 
-#include <memory>
 #include <cassert>
+#include <concepts>
 #include <cstddef>
+#include <memory>
+
 #include "test_macros.h"
 
 struct Pair {
@@ -29,16 +31,16 @@ int main(int, char**) {
   const std::shared_ptr<int> p2 = p1;
   const std::weak_ptr<int> w1(p1);
 
-  assert(p1.owner_hash() == p2.owner_hash());
-  assert(p1.owner_hash() == w1.owner_hash());
+  std::same_as<std::size_t> decltype(auto) hash1 = p1.owner_hash();
+  static_assert(noexcept(p1.owner_hash()));
+
+  assert(hash1 == p2.owner_hash());
+  assert(hash1 == w1.owner_hash());
 
   const std::shared_ptr<Pair> sp(new Pair{1, 2});
   const std::shared_ptr<int> alias(sp, &sp->b);
   assert(static_cast<void*>(sp.get()) != static_cast<void*>(alias.get()));
   assert(sp.owner_hash() == alias.owner_hash());
 
-  ASSERT_SAME_TYPE(decltype(p1.owner_hash()), std::size_t);
-  ASSERT_NOEXCEPT(p1.owner_hash());
-
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp
index 1c6c9e8bd5d67..ddf9bd73906ec 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <memory>
 
@@ -21,13 +21,14 @@
 //     template<class T, class U>
 //         bool operator()(weak_ptr<T> const&, weak_ptr<U> const&) const noexcept;
 //
-//     typedef unspecified is_transparent;
+//     using is_transparent = unspecified;
 // };
 
-#include <memory>
 #include <cassert>
-#include <type_traits>
+#include <concepts>
+#include <memory>
 #include <unordered_set>
+
 #include "test_macros.h"
 
 int main(int, char**) {
@@ -39,7 +40,13 @@ int main(int, char**) {
 
   std::owner_equal oe;
 
-  assert(oe(p1, p2));
+  std::same_as<bool> decltype(auto) result = oe(p1, p2);
+  assert(result);
+  static_assert(noexcept(oe(p1, p2)));
+  static_assert(noexcept(oe(p1, w1)));
+  static_assert(noexcept(oe(w1, p1)));
+  static_assert(noexcept(oe(w1, w1)));
+
   assert(oe(p1, w1));
   assert(oe(w1, p1));
   assert(oe(w1, w1));
@@ -49,13 +56,7 @@ int main(int, char**) {
   assert(!oe(w1, p3));
   assert(!oe(w1, w3));
 
-  ASSERT_SAME_TYPE(decltype(oe(p1, p2)), bool);
-  ASSERT_NOEXCEPT(oe(p1, p2));
-  ASSERT_NOEXCEPT(oe(p1, w1));
-  ASSERT_NOEXCEPT(oe(w1, p1));
-  ASSERT_NOEXCEPT(oe(w1, w1));
-
-  static_assert(std::is_same<std::owner_equal::is_transparent, void>::value, "");
+  static_assert(std::same_as<std::owner_equal::is_transparent, void>);
 
   {
     std::unordered_set<std::weak_ptr<int>, std::owner_hash, std::owner_equal> s;
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp
index 0aaa622246023..e2ada8739a48f 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <memory>
 
@@ -20,9 +20,11 @@
 //     typedef unspecified is_transparent;
 // };
 
-#include <memory>
 #include <cassert>
-#include <type_traits>
+#include <concepts>
+#include <cstddef>
+#include <memory>
+
 #include "test_macros.h"
 
 int main(int, char**) {
@@ -32,18 +34,17 @@ int main(int, char**) {
 
   std::owner_hash oh;
 
-  assert(oh(p1) == p1.owner_hash());
-  assert(oh(w1) == w1.owner_hash());
-
-  assert(oh(p1) == oh(p2));
-  assert(oh(p1) == oh(w1));
+  std::same_as<std::size_t> decltype(auto) hash_p1 = oh(p1);
+  std::same_as<std::size_t> decltype(auto) hash_w1 = oh(w1);
+  static_assert(noexcept(oh(p1)));
+  static_assert(noexcept(oh(w1)));
 
-  ASSERT_SAME_TYPE(decltype(oh(p1)), std::size_t);
-  ASSERT_SAME_TYPE(decltype(oh(w1)), std::size_t);
-  ASSERT_NOEXCEPT(oh(p1));
-  ASSERT_NOEXCEPT(oh(w1));
+  assert(hash_p1 == p1.owner_hash());
+  assert(hash_w1 == w1.owner_hash());
+  assert(hash_p1 == oh(p2));
+  assert(hash_p1 == hash_w1);
 
-  static_assert(std::is_same<std::owner_hash::is_transparent, void>::value, "");
+  static_assert(std::same_as<std::owner_hash::is_transparent, void>);
 
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_shared_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_shared_ptr.pass.cpp
index 35c97a72c8c3c..f71131f7369e3 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_shared_ptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_shared_ptr.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <memory>
 
@@ -14,8 +14,10 @@
 
 // template<class U> bool owner_equal(shared_ptr<U> const& b) const noexcept;
 
-#include <memory>
 #include <cassert>
+#include <concepts>
+#include <memory>
+
 #include "test_macros.h"
 
 int main(int, char**) {
@@ -24,14 +26,14 @@ int main(int, char**) {
   const std::weak_ptr<int> w1(p1);
   const std::weak_ptr<void> empty;
 
-  assert(w1.owner_equal(p1));
+  std::same_as<bool> decltype(auto) result = w1.owner_equal(p1);
+  assert(result);
+  static_assert(noexcept(w1.owner_equal(p1)));
+
   assert(!w1.owner_equal(p3));
 
   const std::shared_ptr<long> empty_sp;
   assert(empty.owner_equal(empty_sp));
 
-  ASSERT_SAME_TYPE(decltype(w1.owner_equal(p1)), bool);
-  ASSERT_NOEXCEPT(w1.owner_equal(p1));
-
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_weak_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_weak_ptr.pass.cpp
index bfd4628edd364..d0e8b6e657673 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_weak_ptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_equal_weak_ptr.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <memory>
 
@@ -14,8 +14,10 @@
 
 // template<class U> bool owner_equal(weak_ptr<U> const& b) const noexcept;
 
-#include <memory>
 #include <cassert>
+#include <concepts>
+#include <memory>
+
 #include "test_macros.h"
 
 int main(int, char**) {
@@ -27,7 +29,10 @@ int main(int, char**) {
   const std::weak_ptr<void> empty1;
   const std::weak_ptr<long> empty2;
 
-  assert(w1.owner_equal(w2));
+  std::same_as<bool> decltype(auto) result = w1.owner_equal(w2);
+  assert(result);
+  static_assert(noexcept(w1.owner_equal(w2)));
+
   assert(w2.owner_equal(w1));
   assert(!w1.owner_equal(w3));
   assert(!w3.owner_equal(w1));
@@ -35,8 +40,5 @@ int main(int, char**) {
   assert(empty1.owner_equal(empty2));
   assert(!w1.owner_equal(empty1));
 
-  ASSERT_SAME_TYPE(decltype(w1.owner_equal(w2)), bool);
-  ASSERT_NOEXCEPT(w1.owner_equal(w2));
-
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_hash.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_hash.pass.cpp
index 772344f1b05de..aac6fec718d5d 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_hash.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.obs/owner_hash.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+// REQUIRES: std-at-least-c++26
 
 // <memory>
 
@@ -14,9 +14,11 @@
 
 // size_t owner_hash() const noexcept;
 
-#include <memory>
 #include <cassert>
+#include <concepts>
 #include <cstddef>
+#include <memory>
+
 #include "test_macros.h"
 
 int main(int, char**) {
@@ -24,11 +26,11 @@ int main(int, char**) {
   const std::weak_ptr<int> w1(p1);
   const std::weak_ptr<int> w2(p1);
 
-  assert(w1.owner_hash() == w2.owner_hash());
-  assert(w1.owner_hash() == p1.owner_hash());
+  std::same_as<std::size_t> decltype(auto) hash1 = w1.owner_hash();
+  static_assert(noexcept(w1.owner_hash()));
 
-  ASSERT_SAME_TYPE(decltype(w1.owner_hash()), std::size_t);
-  ASSERT_NOEXCEPT(w1.owner_hash());
+  assert(hash1 == w2.owner_hash());
+  assert(hash1 == p1.owner_hash());
 
   return 0;
 }

>From bb17b2202cd42b8f66978a5b6efd100fef2c1e40 Mon Sep 17 00:00:00 2001
From: avipatel <aviipatel06 at gmail.com>
Date: Sun, 26 Jul 2026 14:26:45 -0400
Subject: [PATCH 3/4] update: resolve review requests

---
 libcxx/include/memory                                     | 8 ++++----
 .../util.smartptr.ownerequal/owner_equal.pass.cpp         | 3 ++-
 .../util.smartptr.ownerhash/owner_hash.pass.cpp           | 5 +++--
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/libcxx/include/memory b/libcxx/include/memory
index 2c8340aa05082..6a16358324f10 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -823,8 +823,8 @@ struct owner_less<void>
     typedef void is_transparent;
 };
 
-// class owner_hash:                                                          // C++26
-struct owner_hash {
+// struct owner_hash
+struct owner_hash {                                                            // C++26
   template<class T>
     size_t operator()(const shared_ptr<T>&) const noexcept;
 
@@ -834,8 +834,8 @@ struct owner_hash {
   using is_transparent = unspecified;
 };
 
-// class owner_equal:                                                         // C++26
-struct owner_equal {
+// struct owner_equal
+struct owner_equal {                                                           // C++26
   template<class T, class U>
     bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
   template<class T, class U>
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp
index ddf9bd73906ec..ce8580c7547b2 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerequal/owner_equal.pass.cpp
@@ -56,7 +56,8 @@ int main(int, char**) {
   assert(!oe(w1, p3));
   assert(!oe(w1, w3));
 
-  static_assert(std::same_as<std::owner_equal::is_transparent, void>);
+  using member_is_transparent [[maybe_unused]] = std::owner_equal::is_transparent;
+  LIBCPP_STATIC_ASSERT(std::same_as<member_is_transparent, void>);
 
   {
     std::unordered_set<std::weak_ptr<int>, std::owner_hash, std::owner_equal> s;
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp
index e2ada8739a48f..fa0931abe3a3e 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerhash/owner_hash.pass.cpp
@@ -17,7 +17,7 @@
 //     template<class T>
 //         size_t operator()(weak_ptr<T> const&) const noexcept;
 //
-//     typedef unspecified is_transparent;
+//     using is_transparent = unspecified;
 // };
 
 #include <cassert>
@@ -44,7 +44,8 @@ int main(int, char**) {
   assert(hash_p1 == oh(p2));
   assert(hash_p1 == hash_w1);
 
-  static_assert(std::same_as<std::owner_hash::is_transparent, void>);
+  using member_is_transparent [[maybe_unused]] = std::owner_hash::is_transparent;
+  LIBCPP_STATIC_ASSERT(std::same_as<member_is_transparent, void>);
 
   return 0;
 }

>From 00fb80d922f880d85d2bbd291fac76aba968ad07 Mon Sep 17 00:00:00 2001
From: avipatel <aviipatel06 at gmail.com>
Date: Sun, 26 Jul 2026 15:07:29 -0400
Subject: [PATCH 4/4] update: updated rst

---
 libcxx/docs/ReleaseNotes/24.rst | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libcxx/docs/ReleaseNotes/24.rst b/libcxx/docs/ReleaseNotes/24.rst
index 2cd6c83713fe1..4a08287182050 100644
--- a/libcxx/docs/ReleaseNotes/24.rst
+++ b/libcxx/docs/ReleaseNotes/24.rst
@@ -39,6 +39,9 @@ Implemented Papers
 ------------------
 
 - P0493R5: Atomic minimum/maximum (`Github <https://llvm.org/PR105418>`__)
+- P0792R14: ``function_ref`` : a type-erased callable reference (`Github <https://llvm.org/PR105376>`__)
+- P3948R1: ``constant_wrapper`` is the only tool needed for passing constant expressions via function arguments (`Github <https://llvm.org/PR189604>`__)
+- P3961R1: Less double indirection in ``function_ref`` (RU-220) (`Github <https://llvm.org/PR189606>`__)
 - P1901R2: Enabling the Use of ``weak_ptr`` as Keys in Unordered Associative Containers (`Github <https://llvm.org/PR105372>`__)
 
 Improvements and New Features
@@ -72,5 +75,4 @@ ABI Affecting Changes
   macro was provided as an escape hatch, but it has been removed in LLVM 24 since there was no evidence of it being useful.
 
 Build System Changes
---------------------
-
+--------------------
\ No newline at end of file



More information about the libcxx-commits mailing list