CommonLibSSE NG
hkRefPtr.h
Go to the documentation of this file.
1 #pragma once
2 
3 namespace RE
4 {
5  template <class T>
6  class hkRefPtr
7  {
8  public:
9  using element_type = T;
10 
11  // 1
12  inline constexpr hkRefPtr() noexcept :
13  _ptr(nullptr)
14  {}
15 
16  // 2
17  inline constexpr hkRefPtr(std::nullptr_t) noexcept :
18  _ptr(nullptr)
19  {}
20 
21  // 3
22  template <
23  class Y,
24  std::enable_if_t<
25  std::is_convertible_v<
26  Y*,
27  element_type*>,
28  int> = 0>
29  inline explicit hkRefPtr(Y* a_rhs) :
30  _ptr(a_rhs)
31  {
32  TryAttach();
33  }
34 
35  // 9a
36  inline hkRefPtr(const hkRefPtr& a_rhs) :
37  _ptr(a_rhs._ptr)
38  {
39  TryAttach();
40  }
41 
42  // 9b
43  template <
44  class Y,
45  std::enable_if_t<
46  std::is_convertible_v<
47  Y*,
48  element_type*>,
49  int> = 0>
50  inline hkRefPtr(const hkRefPtr<Y>& a_rhs) :
51  _ptr(a_rhs._ptr)
52  {
53  TryAttach();
54  }
55 
56  // 10a
57  inline hkRefPtr(hkRefPtr&& a_rhs) noexcept :
58  _ptr(std::move(a_rhs._ptr))
59  {
60  a_rhs._ptr = nullptr;
61  }
62 
63  // 10b
64  template <
65  class Y,
66  std::enable_if_t<
67  std::is_convertible_v<
68  Y*,
69  element_type*>,
70  int> = 0>
71  inline hkRefPtr(hkRefPtr<Y>&& a_rhs) noexcept :
72  _ptr(std::move(a_rhs._ptr))
73  {
74  a_rhs._ptr = nullptr;
75  }
76 
77  inline ~hkRefPtr()
78  {
79  TryDetach();
80  }
81 
82  // 1a
83  inline hkRefPtr& operator=(const hkRefPtr& a_rhs)
84  {
85  if (this != std::addressof(a_rhs)) {
86  TryDetach();
87  _ptr = a_rhs._ptr;
88  TryAttach();
89  }
90  return *this;
91  }
92 
93  // 1b
94  template <
95  class Y,
96  std::enable_if_t<
97  std::is_convertible_v<
98  Y*,
99  element_type*>,
100  int> = 0>
101  inline hkRefPtr& operator=(const hkRefPtr<Y>& a_rhs)
102  {
103  TryDetach();
104  _ptr = a_rhs._ptr;
105  TryAttach();
106  return *this;
107  }
108 
109  // 2a
110  inline hkRefPtr& operator=(hkRefPtr&& a_rhs)
111  {
112  if (this != std::addressof(a_rhs)) {
113  TryDetach();
114  _ptr = std::move(a_rhs._ptr);
115  a_rhs._ptr = nullptr;
116  }
117  return *this;
118  }
119 
120  // 2b
121  template <
122  class Y,
123  std::enable_if_t<
124  std::is_convertible_v<
125  Y*,
126  element_type*>,
127  int> = 0>
128  inline hkRefPtr& operator=(hkRefPtr<Y>&& a_rhs)
129  {
130  TryDetach();
131  _ptr = std::move(a_rhs._ptr);
132  a_rhs._ptr = nullptr;
133  return *this;
134  }
135 
136  inline void reset()
137  {
138  TryDetach();
139  }
140 
141  template <
142  class Y,
143  std::enable_if_t<
144  std::is_convertible_v<
145  Y*,
146  element_type*>,
147  int> = 0>
148  inline void reset(Y* a_ptr)
149  {
150  if (_ptr != a_ptr) {
151  TryDetach();
152  _ptr = a_ptr;
153  TryAttach();
154  }
155  }
156 
157  [[nodiscard]] constexpr element_type* get() const noexcept
158  {
159  return _ptr;
160  }
161 
162  [[nodiscard]] explicit constexpr operator bool() const noexcept
163  {
164  return static_cast<bool>(_ptr);
165  }
166 
167  [[nodiscard]] constexpr element_type& operator*() const noexcept
168  {
169  assert(static_cast<bool>(*this));
170  return *_ptr;
171  }
172 
173  [[nodiscard]] constexpr element_type* operator->() const noexcept
174  {
175  assert(static_cast<bool>(*this));
176  return _ptr;
177  }
178 
179  protected:
180  template <class>
181  friend class hkRefPtr;
182 
183  void TryAttach()
184  {
185  if (_ptr) {
186  _ptr->AddReference();
187  }
188  }
189 
190  void TryDetach()
191  {
192  if (_ptr) {
193  _ptr->RemoveReference();
194  _ptr = nullptr;
195  }
196  }
197 
198  // members
200  };
201  static_assert(sizeof(hkRefPtr<void*>) == 0x8);
202 
203  template <class T, class... Args>
204  [[nodiscard]] inline hkRefPtr<T> make_hkref(Args&&... a_args)
205  {
206  return hkRefPtr<T>{ new T(std::forward<Args>(a_args)...) };
207  }
208 
209  template <class T1, class T2>
210  [[nodiscard]] constexpr bool operator==(const hkRefPtr<T1>& a_lhs, const hkRefPtr<T2>& a_rhs)
211  {
212  return a_lhs.get() == a_rhs.get();
213  }
214 
215  template <class T1, class T2>
216  [[nodiscard]] constexpr bool operator!=(const hkRefPtr<T1>& a_lhs, const hkRefPtr<T2>& a_rhs)
217  {
218  return !(a_lhs == a_rhs);
219  }
220 
221  template <class T>
222  [[nodiscard]] constexpr bool operator==(const hkRefPtr<T>& a_lhs, std::nullptr_t) noexcept
223  {
224  return !a_lhs;
225  }
226 
227  template <class T>
228  [[nodiscard]] constexpr bool operator==(std::nullptr_t, const hkRefPtr<T>& a_rhs) noexcept
229  {
230  return !a_rhs;
231  }
232 
233  template <class T>
234  [[nodiscard]] constexpr bool operator!=(const hkRefPtr<T>& a_lhs, std::nullptr_t) noexcept
235  {
236  return static_cast<bool>(a_lhs);
237  }
238 
239  template <class T>
240  [[nodiscard]] constexpr bool operator!=(std::nullptr_t, const hkRefPtr<T>& a_rhs) noexcept
241  {
242  return static_cast<bool>(a_rhs);
243  }
244 
245  template <class T>
247 }
Definition: hkRefPtr.h:7
hkRefPtr(const hkRefPtr< Y > &a_rhs)
Definition: hkRefPtr.h:50
hkRefPtr(const hkRefPtr &a_rhs)
Definition: hkRefPtr.h:36
hkRefPtr & operator=(const hkRefPtr &a_rhs)
Definition: hkRefPtr.h:83
constexpr element_type * get() const noexcept
Definition: hkRefPtr.h:157
constexpr element_type * operator->() const noexcept
Definition: hkRefPtr.h:173
hkRefPtr & operator=(const hkRefPtr< Y > &a_rhs)
Definition: hkRefPtr.h:101
T element_type
Definition: hkRefPtr.h:9
constexpr element_type & operator*() const noexcept
Definition: hkRefPtr.h:167
void reset(Y *a_ptr)
Definition: hkRefPtr.h:148
void TryAttach()
Definition: hkRefPtr.h:183
void TryDetach()
Definition: hkRefPtr.h:190
hkRefPtr(Y *a_rhs)
Definition: hkRefPtr.h:29
hkRefPtr(hkRefPtr &&a_rhs) noexcept
Definition: hkRefPtr.h:57
hkRefPtr & operator=(hkRefPtr< Y > &&a_rhs)
Definition: hkRefPtr.h:128
~hkRefPtr()
Definition: hkRefPtr.h:77
constexpr hkRefPtr() noexcept
Definition: hkRefPtr.h:12
constexpr hkRefPtr(std::nullptr_t) noexcept
Definition: hkRefPtr.h:17
void reset()
Definition: hkRefPtr.h:136
hkRefPtr & operator=(hkRefPtr &&a_rhs)
Definition: hkRefPtr.h:110
element_type * _ptr
Definition: hkRefPtr.h:199
hkRefPtr(hkRefPtr< Y > &&a_rhs) noexcept
Definition: hkRefPtr.h:71
Definition: AbsorbEffect.h:6
constexpr bool operator==(const BSTSmartPointer< T1 > &a_lhs, const BSTSmartPointer< T2 > &a_rhs)
Definition: BSTSmartPointer.h:240
hkRefPtr(T *) -> hkRefPtr< T >
constexpr bool operator!=(const BSTSmartPointer< T1 > &a_lhs, const BSTSmartPointer< T2 > &a_rhs)
Definition: BSTSmartPointer.h:246
hkRefPtr< T > make_hkref(Args &&... a_args)
Definition: hkRefPtr.h:204