From 272bbc400df542dbe2ed0fe0d40112318cde0689 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Tue, 2 Jan 2024 03:47:42 -0800
Subject: Properly handle the atomic unique_ptr type deleter

---
 common/atomic.h | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

(limited to 'common/atomic.h')

diff --git a/common/atomic.h b/common/atomic.h
index 8e75cb0e..4eb49598 100644
--- a/common/atomic.h
+++ b/common/atomic.h
@@ -35,26 +35,28 @@ template<typename T, typename D=std::default_delete<T>>
 class atomic_unique_ptr {
     std::atomic<gsl::owner<T*>> mPointer{};
 
+    using unique_ptr_t = std::unique_ptr<T,D>;
+
 public:
     atomic_unique_ptr() = default;
     atomic_unique_ptr(const atomic_unique_ptr&) = delete;
     explicit atomic_unique_ptr(std::nullptr_t) noexcept { }
     explicit atomic_unique_ptr(gsl::owner<T*> ptr) noexcept : mPointer{ptr} { }
-    explicit atomic_unique_ptr(std::unique_ptr<T>&& rhs) noexcept : mPointer{rhs.release()} { }
+    explicit atomic_unique_ptr(unique_ptr_t&& rhs) noexcept : mPointer{rhs.release()} { }
     ~atomic_unique_ptr()
     {
         if(auto ptr = mPointer.exchange(nullptr, std::memory_order_relaxed))
             D{}(ptr);
     }
 
-    atomic_unique_ptr& operator=(const atomic_unique_ptr&) = delete;
-    atomic_unique_ptr& operator=(std::nullptr_t) noexcept
+    auto operator=(const atomic_unique_ptr&) -> atomic_unique_ptr& = delete;
+    auto operator=(std::nullptr_t) noexcept -> atomic_unique_ptr&
     {
         if(auto ptr = mPointer.exchange(nullptr))
             D{}(ptr);
         return *this;
     }
-    atomic_unique_ptr& operator=(std::unique_ptr<T>&& rhs) noexcept
+    auto operator=(unique_ptr_t&& rhs) noexcept -> atomic_unique_ptr&
     {
         if(auto ptr = mPointer.exchange(rhs.release()))
             D{}(ptr);
@@ -62,7 +64,8 @@ public:
     }
 
     [[nodiscard]]
-    T* load(std::memory_order m=std::memory_order_seq_cst) const { return mPointer.load(m); }
+    auto load(std::memory_order m=std::memory_order_seq_cst) const noexcept -> T*
+    { return mPointer.load(m); }
     void store(std::nullptr_t, std::memory_order m=std::memory_order_seq_cst) noexcept
     {
         if(auto oldptr = mPointer.exchange(nullptr, m))
@@ -73,24 +76,24 @@ public:
         if(auto oldptr = mPointer.exchange(ptr, m))
             D{}(oldptr);
     }
-    void store(std::unique_ptr<T>&& ptr, std::memory_order m=std::memory_order_seq_cst) noexcept
+    void store(unique_ptr_t&& ptr, std::memory_order m=std::memory_order_seq_cst) noexcept
     {
         if(auto oldptr = mPointer.exchange(ptr.release(), m))
             D{}(oldptr);
     }
 
     [[nodiscard]]
-    std::unique_ptr<T> exchange(std::nullptr_t, std::memory_order m=std::memory_order_seq_cst) noexcept
-    { return std::unique_ptr<T>{mPointer.exchange(nullptr, m)}; }
+    auto exchange(std::nullptr_t, std::memory_order m=std::memory_order_seq_cst) noexcept -> unique_ptr_t
+    { return unique_ptr_t{mPointer.exchange(nullptr, m)}; }
     [[nodiscard]]
-    std::unique_ptr<T> exchange(gsl::owner<T*> ptr, std::memory_order m=std::memory_order_seq_cst) noexcept
-    { return std::unique_ptr<T>{mPointer.exchange(ptr, m)}; }
+    auto exchange(gsl::owner<T*> ptr, std::memory_order m=std::memory_order_seq_cst) noexcept -> unique_ptr_t
+    { return unique_ptr_t{mPointer.exchange(ptr, m)}; }
     [[nodiscard]]
-    std::unique_ptr<T> exchange(std::unique_ptr<T>&& ptr, std::memory_order m=std::memory_order_seq_cst) noexcept
-    { return std::unique_ptr<T>{mPointer.exchange(ptr.release(), m)}; }
+    auto exchange(std::unique_ptr<T>&& ptr, std::memory_order m=std::memory_order_seq_cst) noexcept -> unique_ptr_t
+    { return unique_ptr_t{mPointer.exchange(ptr.release(), m)}; }
 
     [[nodiscard]]
-    bool is_lock_free() const noexcept { mPointer.is_lock_free(); }
+    auto is_lock_free() const noexcept -> bool { mPointer.is_lock_free(); }
 
     static constexpr auto is_always_lock_free = std::atomic<gsl::owner<T*>>::is_always_lock_free;
 };
-- 
cgit v1.2.3