Sleipnir C++ API
Loading...
Searching...
No Matches
IntrusiveSharedPtr.hpp
Go to the documentation of this file.
1// Copyright (c) Sleipnir contributors
2
3#pragma once
4
5#include <concepts>
6#include <cstddef>
7#include <memory>
8#include <utility>
9
10namespace sleipnir {
11
28template <typename T>
30 public:
31 template <typename>
32 friend class IntrusiveSharedPtr;
33
38
43
48 explicit constexpr IntrusiveSharedPtr(T* ptr) noexcept : m_ptr{ptr} {
49 if (m_ptr != nullptr) {
50 IntrusiveSharedPtrIncRefCount(m_ptr);
51 }
52 }
53
54 constexpr ~IntrusiveSharedPtr() {
55 if (m_ptr != nullptr) {
56 IntrusiveSharedPtrDecRefCount(m_ptr);
57 }
58 }
59
64 : m_ptr{rhs.m_ptr} {
65 if (m_ptr != nullptr) {
66 IntrusiveSharedPtrIncRefCount(m_ptr);
67 }
68 }
69
73 template <typename U>
74 requires(!std::same_as<T, U> && std::convertible_to<U*, T*>)
75 constexpr IntrusiveSharedPtr( // NOLINT
77 : m_ptr{rhs.m_ptr} {
78 if (m_ptr != nullptr) {
79 IntrusiveSharedPtrIncRefCount(m_ptr);
80 }
81 }
82
86 constexpr IntrusiveSharedPtr<T>& operator=( // NOLINT
87 const IntrusiveSharedPtr<T>& rhs) noexcept {
88 if (m_ptr == rhs.m_ptr) {
89 return *this;
90 }
91
92 if (m_ptr != nullptr) {
93 IntrusiveSharedPtrDecRefCount(m_ptr);
94 }
95
96 m_ptr = rhs.m_ptr;
97
98 if (m_ptr != nullptr) {
99 IntrusiveSharedPtrIncRefCount(m_ptr);
100 }
101
102 return *this;
103 }
104
108 template <typename U>
109 requires(!std::same_as<T, U> && std::convertible_to<U*, T*>)
110 constexpr IntrusiveSharedPtr<T>& operator=( // NOLINT
111 const IntrusiveSharedPtr<U>& rhs) noexcept {
112 if (m_ptr == rhs.m_ptr) {
113 return *this;
114 }
115
116 if (m_ptr != nullptr) {
117 IntrusiveSharedPtrDecRefCount(m_ptr);
118 }
119
120 m_ptr = rhs.m_ptr;
121
122 if (m_ptr != nullptr) {
123 IntrusiveSharedPtrIncRefCount(m_ptr);
124 }
125
126 return *this;
127 }
128
133 : m_ptr{std::exchange(rhs.m_ptr, nullptr)} {}
134
138 template <typename U>
139 requires(!std::same_as<T, U> && std::convertible_to<U*, T*>)
140 constexpr IntrusiveSharedPtr( // NOLINT
142 : m_ptr{std::exchange(rhs.m_ptr, nullptr)} {}
143
148 IntrusiveSharedPtr<T>&& rhs) noexcept {
149 if (m_ptr == rhs.m_ptr) {
150 return *this;
151 }
152
153 std::swap(m_ptr, rhs.m_ptr);
154
155 return *this;
156 }
157
161 template <typename U>
162 requires(!std::same_as<T, U> && std::convertible_to<U*, T*>)
163 constexpr IntrusiveSharedPtr<T>& operator=(
164 IntrusiveSharedPtr<U>&& rhs) noexcept {
165 if (m_ptr == rhs.m_ptr) {
166 return *this;
167 }
168
169 std::swap(m_ptr, rhs.m_ptr);
170
171 return *this;
172 }
173
177 constexpr T* Get() const noexcept { return m_ptr; }
178
182 constexpr T& operator*() const noexcept { return *m_ptr; }
183
187 constexpr T* operator->() const noexcept { return m_ptr; }
188
192 explicit constexpr operator bool() const noexcept { return m_ptr != nullptr; }
193
198 friend constexpr bool operator==(const IntrusiveSharedPtr<T>& lhs,
199 const IntrusiveSharedPtr<T>& rhs) noexcept {
200 return lhs.m_ptr == rhs.m_ptr;
201 }
202
207 friend constexpr bool operator!=(const IntrusiveSharedPtr<T>& lhs,
208 const IntrusiveSharedPtr<T>& rhs) noexcept {
209 return lhs.m_ptr != rhs.m_ptr;
210 }
211
215 friend constexpr bool operator==(const IntrusiveSharedPtr<T>& lhs,
216 std::nullptr_t) noexcept {
217 return lhs.m_ptr == nullptr;
218 }
219
223 friend constexpr bool operator==(std::nullptr_t,
224 const IntrusiveSharedPtr<T>& rhs) noexcept {
225 return nullptr == rhs.m_ptr;
226 }
227
232 friend constexpr bool operator!=(const IntrusiveSharedPtr<T>& lhs,
233 std::nullptr_t) noexcept {
234 return lhs.m_ptr != nullptr;
235 }
236
241 friend constexpr bool operator!=(std::nullptr_t,
242 const IntrusiveSharedPtr<T>& rhs) noexcept {
243 return nullptr != rhs.m_ptr;
244 }
245
246 private:
247 T* m_ptr = nullptr;
248};
249
258template <typename T, typename... Args>
260 return IntrusiveSharedPtr<T>{new T(std::forward<Args>(args)...)};
261}
262
274template <typename T, typename Alloc, typename... Args>
276 auto ptr = std::allocator_traits<Alloc>::allocate(alloc, sizeof(T));
277 std::allocator_traits<Alloc>::construct(alloc, ptr,
278 std::forward<Args>(args)...);
279 return IntrusiveSharedPtr<T>{ptr};
280}
281
282} // namespace sleipnir
Definition IntrusiveSharedPtr.hpp:29
constexpr IntrusiveSharedPtr(IntrusiveSharedPtr< U > &&rhs) noexcept
Definition IntrusiveSharedPtr.hpp:140
friend constexpr bool operator==(std::nullptr_t, const IntrusiveSharedPtr< T > &rhs) noexcept
Definition IntrusiveSharedPtr.hpp:223
constexpr IntrusiveSharedPtr< T > & operator=(IntrusiveSharedPtr< T > &&rhs) noexcept
Definition IntrusiveSharedPtr.hpp:147
constexpr T * Get() const noexcept
Definition IntrusiveSharedPtr.hpp:177
friend constexpr bool operator!=(const IntrusiveSharedPtr< T > &lhs, std::nullptr_t) noexcept
Definition IntrusiveSharedPtr.hpp:232
constexpr IntrusiveSharedPtr< T > & operator=(const IntrusiveSharedPtr< T > &rhs) noexcept
Definition IntrusiveSharedPtr.hpp:86
friend constexpr bool operator==(const IntrusiveSharedPtr< T > &lhs, std::nullptr_t) noexcept
Definition IntrusiveSharedPtr.hpp:215
constexpr ~IntrusiveSharedPtr()
Definition IntrusiveSharedPtr.hpp:54
friend constexpr bool operator==(const IntrusiveSharedPtr< T > &lhs, const IntrusiveSharedPtr< T > &rhs) noexcept
Definition IntrusiveSharedPtr.hpp:198
constexpr IntrusiveSharedPtr(const IntrusiveSharedPtr< U > &rhs) noexcept
Definition IntrusiveSharedPtr.hpp:75
constexpr IntrusiveSharedPtr(T *ptr) noexcept
Definition IntrusiveSharedPtr.hpp:48
constexpr T & operator*() const noexcept
Definition IntrusiveSharedPtr.hpp:182
constexpr IntrusiveSharedPtr() noexcept=default
friend constexpr bool operator!=(std::nullptr_t, const IntrusiveSharedPtr< T > &rhs) noexcept
Definition IntrusiveSharedPtr.hpp:241
constexpr IntrusiveSharedPtr(const IntrusiveSharedPtr< T > &rhs) noexcept
Definition IntrusiveSharedPtr.hpp:63
constexpr T * operator->() const noexcept
Definition IntrusiveSharedPtr.hpp:187
constexpr IntrusiveSharedPtr(IntrusiveSharedPtr< T > &&rhs) noexcept
Definition IntrusiveSharedPtr.hpp:132
friend constexpr bool operator!=(const IntrusiveSharedPtr< T > &lhs, const IntrusiveSharedPtr< T > &rhs) noexcept
Definition IntrusiveSharedPtr.hpp:207
Definition Expression.hpp:18
IntrusiveSharedPtr< T > AllocateIntrusiveShared(Alloc alloc, Args &&... args)
Definition IntrusiveSharedPtr.hpp:275
IntrusiveSharedPtr< T > MakeIntrusiveShared(Args &&... args)
Definition IntrusiveSharedPtr.hpp:259