Cuberite
A lightweight, fast and extensible game server for Minecraft
AtomicUniquePtr.h
Go to the documentation of this file.
1 
2 
3 #pragma once
4 
5 
7 template <typename T>
9 {
10 public:
11  static_assert(!std::is_array<T>::value, "cAtomicUniquePtr does not support arrays");
13 
14  cAtomicUniquePtr() noexcept:
15  m_Ptr(nullptr)
16  {
17  }
18 
19 
20  cAtomicUniquePtr(std::unique_ptr<T> a_Ptr) noexcept:
21  m_Ptr(a_Ptr.release())
22  {
23  }
24 
25  cAtomicUniquePtr & operator = (std::unique_ptr<T> a_Ptr) noexcept
26  {
27  store(std::move(a_Ptr));
28  return *this;
29  }
30 
31  ~cAtomicUniquePtr() noexcept
32  {
33  delete load();
34  }
35 
36  operator T * () const noexcept
37  {
38  return load();
39  }
40 
41  bool compare_exchange_weak(T *& a_Expected, std::unique_ptr<T> && a_Desired, std::memory_order a_Order = std::memory_order_seq_cst) noexcept
42  {
43  bool DidExchange = m_Ptr.compare_exchange_weak(a_Expected, a_Desired.get(), a_Order);
44  if (DidExchange)
45  {
46  // Only release ownership from the caller if the exchange occurred
47  a_Desired.release();
48  }
49  return DidExchange;
50  }
51 
52  bool compare_exchange_strong(T *& a_Expected, std::unique_ptr<T> && a_Desired, std::memory_order a_Order = std::memory_order_seq_cst) noexcept
53  {
54  bool DidExchange = m_Ptr.compare_exchange_strong(a_Expected, a_Desired.get(), a_Order);
55  if (DidExchange)
56  {
57  // Only release ownership from the caller if the exchange occurred
58  a_Desired.release();
59  }
60  return DidExchange;
61  }
62 
63  std::unique_ptr<T> exchange(std::unique_ptr<T> a_Ptr, std::memory_order a_Order = std::memory_order_seq_cst) noexcept
64  {
65  return std::unique_ptr<T>{ m_Ptr.exchange(a_Ptr.release(), a_Order) };
66  }
67 
68  T * load(std::memory_order a_Order = std::memory_order_seq_cst) const noexcept
69  {
70  return m_Ptr.load(a_Order);
71  }
72 
73  void store(std::unique_ptr<T> a_Ptr, std::memory_order a_Order = std::memory_order_seq_cst) noexcept
74  {
75  // Store new value and delete old value
76  delete m_Ptr.exchange(a_Ptr.release(), a_Order);
77  }
78 
79 private:
80  std::atomic<T*> m_Ptr;
81 };
An RAII wrapper for std::atomic<T*>.
void store(std::unique_ptr< T > a_Ptr, std::memory_order a_Order=std::memory_order_seq_cst) noexcept
cAtomicUniquePtr & operator=(std::unique_ptr< T > a_Ptr) noexcept
DISALLOW_COPY_AND_ASSIGN(cAtomicUniquePtr)
std::unique_ptr< T > exchange(std::unique_ptr< T > a_Ptr, std::memory_order a_Order=std::memory_order_seq_cst) noexcept
cAtomicUniquePtr(std::unique_ptr< T > a_Ptr) noexcept
std::atomic< T * > m_Ptr
bool compare_exchange_strong(T *&a_Expected, std::unique_ptr< T > &&a_Desired, std::memory_order a_Order=std::memory_order_seq_cst) noexcept
cAtomicUniquePtr() noexcept
~cAtomicUniquePtr() noexcept
bool compare_exchange_weak(T *&a_Expected, std::unique_ptr< T > &&a_Desired, std::memory_order a_Order=std::memory_order_seq_cst) noexcept
T * load(std::memory_order a_Order=std::memory_order_seq_cst) const noexcept