[libcxx-commits] [libcxx] [libcxx][test-support] Improve thread_unsafe_shared_ptr (PR #195932)

Nikita Belenkiy via libcxx-commits libcxx-commits at lists.llvm.org
Mon Sep 14 12:03:25 PDT 2026


https://github.com/kitsnet updated https://github.com/llvm/llvm-project/pull/195932

>From 34ac338104d6a3adc7bfa53c875c1d57d2a5f100 Mon Sep 17 00:00:00 2001
From: Nikita Belenkiy <nikita.nb.belenkiy at partner.bmw.de>
Date: Tue, 5 May 2026 22:17:44 +0200
Subject: [PATCH] [libcxx][test-support] Improve thread_unsafe_shared_ptr

Adapting test support class thread_unsafe_shared_ptr for future use
with fancy_pointer_allocator, in particular, in constexpr contexts:

* Implementing the rule of 5;
* Annotating noexcept methods
---
 libcxx/test/support/test_allocator.h | 45 ++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 12 deletions(-)

diff --git a/libcxx/test/support/test_allocator.h b/libcxx/test/support/test_allocator.h
index 60845fa35a086..ece1a27259b76 100644
--- a/libcxx/test/support/test_allocator.h
+++ b/libcxx/test/support/test_allocator.h
@@ -421,21 +421,30 @@ namespace detail {
 template <class T>
 class thread_unsafe_shared_ptr {
 public:
-  thread_unsafe_shared_ptr() = default;
-
-  TEST_CONSTEXPR_CXX14 thread_unsafe_shared_ptr(const thread_unsafe_shared_ptr& other) : block(other.block) {
+  // as it's internal and technically not nullable, we don't care about null pointer state
+  // and don't need destructive move
+  TEST_CONSTEXPR_CXX14 thread_unsafe_shared_ptr(const thread_unsafe_shared_ptr& other) // TODO: TEST_NOEXCEPT
+      : block(other.block) {
     ++block->ref_count;
   }
-
-  TEST_CONSTEXPR_CXX20 ~thread_unsafe_shared_ptr() {
-    --block->ref_count;
-    if (block->ref_count != 0)
-      return;
-    typedef std::allocator_traits<std::allocator<control_block> > allocator_traits;
-    std::allocator<control_block> alloc;
-    allocator_traits::destroy(alloc, block);
-    allocator_traits::deallocate(alloc, block, 1);
+  TEST_CONSTEXPR_CXX14 thread_unsafe_shared_ptr(thread_unsafe_shared_ptr&& other) TEST_NOEXCEPT : block(other.block) {
+    ++block->ref_count;
+  }
+  TEST_CONSTEXPR_CXX14 thread_unsafe_shared_ptr& operator=(const thread_unsafe_shared_ptr& other) TEST_NOEXCEPT {
+    // self-assignment safe order
+    ++other.block->ref_count;
+    detach_control_block();
+    block = other.block;
+    return *this;
   }
+  TEST_CONSTEXPR_CXX20 thread_unsafe_shared_ptr& operator=(thread_unsafe_shared_ptr&& other) TEST_NOEXCEPT {
+    // self-assignment safe order
+    ++other.block->ref_count;
+    detach_control_block();
+    block = other.block;
+    return *this;
+  }
+  TEST_CONSTEXPR_CXX20 ~thread_unsafe_shared_ptr() TEST_NOEXCEPT { detach_control_block(); }
 
   TEST_CONSTEXPR const T& operator*() const { return block->content; }
   TEST_CONSTEXPR const T* operator->() const { return &block->content; }
@@ -452,6 +461,18 @@ class thread_unsafe_shared_ptr {
     T content;
   };
 
+  thread_unsafe_shared_ptr() = default;
+
+  TEST_CONSTEXPR_CXX20 void detach_control_block() {
+    --block->ref_count;
+    if (block->ref_count != 0)
+      return;
+    typedef std::allocator_traits<std::allocator<control_block> > allocator_traits;
+    std::allocator<control_block> alloc;
+    allocator_traits::destroy(alloc, block);
+    allocator_traits::deallocate(alloc, block, 1);
+  }
+
   control_block* block = nullptr;
 
   template <class U, class... Args>



More information about the libcxx-commits mailing list