cesium-native 0.44.2
Loading...
Searching...
No Matches
IntrusivePointer.h
1#pragma once
2#include <type_traits>
3#include <utility>
4
5namespace CesiumUtility {
6
19template <class T> class IntrusivePointer final {
20public:
24 IntrusivePointer(T* p = nullptr) noexcept : _p(p) { this->addReference(); }
25
29 IntrusivePointer(const IntrusivePointer<T>& rhs) noexcept : _p(rhs._p) {
30 this->addReference();
31 }
32
40 template <class U>
41 IntrusivePointer(const IntrusivePointer<U>& rhs) noexcept : _p(rhs._p) {
42 this->addReference();
43 }
44
49 : _p(std::exchange(rhs._p, nullptr)) {
50 // Reference count is unchanged
51 }
52
60 template <class U>
62 : _p(std::exchange(rhs._p, nullptr)) {
63 // Reference count is unchanged
64 }
65
69 ~IntrusivePointer() noexcept { this->releaseReference(); }
70
80 template <typename... ConstructorArgumentTypes>
81 T& emplace(ConstructorArgumentTypes&&... constructorArguments) {
82 *this =
83 new T(std::forward<ConstructorArgumentTypes>(constructorArguments)...);
84 return *this->get();
85 }
86
90 void reset() { *this = nullptr; }
91
95 // NOLINTNEXTLINE(bugprone-unhandled-self-assignment)
97 if (*this != rhs) {
98 // addReference the new pointer before releaseReference'ing the old.
99 T* pOld = this->_p;
100 this->_p = rhs._p;
101 addReference();
102
103 if (pOld) {
104 pOld->releaseReference();
105 }
106 }
107
108 return *this;
109 }
110
115 template <class U>
117 if (*this != rhs) {
118 // addReference the new pointer before releaseReference'ing the old.
119 T* pOld = this->_p;
120 this->_p = rhs._p;
121 addReference();
122
123 if (pOld) {
124 pOld->releaseReference();
125 }
126 }
127
128 return *this;
129 }
130
135 if (this->_p != rhs._p) {
136 std::swap(this->_p, rhs._p);
137 }
138
139 return *this;
140 }
141
145 IntrusivePointer& operator=(T* p) noexcept {
146 if (this->_p != p) {
147 // addReference the new pointer before releaseReference'ing the old.
148 T* pOld = this->_p;
149 this->_p = p;
150 addReference();
151
152 if (pOld) {
153 pOld->releaseReference();
154 }
155 }
156
157 return *this;
158 }
159
163 T& operator*() const noexcept { return *this->_p; }
164
168 T* operator->() const noexcept { return this->_p; }
169
174 explicit operator bool() const noexcept { return this->_p != nullptr; }
175
179 T* get() const noexcept { return this->_p; }
180
184 bool operator==(const IntrusivePointer<T>& rhs) const noexcept {
185 return this->_p == rhs._p;
186 }
187
189 template <class U>
190 bool operator==(const IntrusivePointer<U>& rhs) const noexcept {
191 return this->_p == rhs._p;
192 }
193
197 bool operator!=(const IntrusivePointer<T>& rhs) const noexcept {
198 return !(*this == rhs);
199 }
200
204 template <class U>
205 bool operator!=(const IntrusivePointer<U>& rhs) const noexcept {
206 return !(*this == rhs);
207 }
208
213 bool operator==(const T* pRhs) const noexcept { return this->_p == pRhs; }
214
219 bool operator!=(const T* pRhs) const noexcept { return !(*this == pRhs); }
220
221private:
222 void addReference() noexcept {
223 if (this->_p) {
224 this->_p->addReference();
225 }
226 }
227
228 void releaseReference() noexcept {
229 if (this->_p) {
230 this->_p->releaseReference();
231 }
232 }
233
234 T* _p;
235 template <typename U> friend class IntrusivePointer;
236};
237
244template <typename T, typename U>
245IntrusivePointer<T>
247 return IntrusivePointer<T>(const_cast<T*>(p.get()));
248}
249
250} // namespace CesiumUtility
A smart pointer that calls addReference and releaseReference on the controlled object.
bool operator==(const IntrusivePointer< T > &rhs) const noexcept
Returns true if two pointers are equal.
T * operator->() const noexcept
Arrow operator.
bool operator==(const IntrusivePointer< U > &rhs) const noexcept
Returns true if two pointers are equal.
IntrusivePointer & operator=(const IntrusivePointer &rhs) noexcept
Assignment operator.
IntrusivePointer(IntrusivePointer< T > &&rhs) noexcept
Move constructor.
IntrusivePointer & operator=(IntrusivePointer &&rhs) noexcept
Move assignment operator.
bool operator!=(const T *pRhs) const noexcept
Returns true if the contents of this pointer is not equal to the given pointer.
T & operator*() const noexcept
Dereferencing operator.
IntrusivePointer(IntrusivePointer< U > &&rhs) noexcept
Implicit conversion of an r-value to a pointer to a base (or otherwise convertible) type.
bool operator!=(const IntrusivePointer< U > &rhs) const noexcept
Returns true if two pointers are not equal.
void reset()
Reset this pointer to nullptr.
IntrusivePointer & operator=(const IntrusivePointer< U > &rhs) noexcept
Assigns an IntrusivePointer of another type to this IntrusivePointer.
IntrusivePointer(const IntrusivePointer< T > &rhs) noexcept
Copy constructor.
bool operator!=(const IntrusivePointer< T > &rhs) const noexcept
Returns true if two pointers are not equal.
IntrusivePointer(const IntrusivePointer< U > &rhs) noexcept
Implicit conversion to a pointer to a base (or otherwise convertible) type.
IntrusivePointer & operator=(T *p) noexcept
Assignment operator.
~IntrusivePointer() noexcept
Default destructor.
IntrusivePointer(T *p=nullptr) noexcept
Default constructor.
T * get() const noexcept
Returns the internal pointer.
T & emplace(ConstructorArgumentTypes &&... constructorArguments)
Constructs a new instance and assigns it to this IntrusivePointer. If this IntrusivePointer already p...
bool operator==(const T *pRhs) const noexcept
Returns true if the contents of this pointer is equal to the given pointer.
Utility classes for Cesium.
IntrusivePointer< T > const_intrusive_cast(const IntrusivePointer< U > &p) noexcept
Casts a const IntrusivePointer to its non-const equivalent.