cesium-native 0.43.0
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
96 if (this->_p != rhs._p) {
97 // addReference the new pointer before releaseReference'ing the old.
98 T* pOld = this->_p;
99 this->_p = rhs._p;
100 addReference();
101
102 if (pOld) {
103 pOld->releaseReference();
104 }
105 }
106
107 return *this;
108 }
109
114 template <class U>
116 if (this->_p != rhs._p) {
117 // addReference the new pointer before releaseReference'ing the old.
118 T* pOld = this->_p;
119 this->_p = rhs._p;
120 addReference();
121
122 if (pOld) {
123 pOld->releaseReference();
124 }
125 }
126
127 return *this;
128 }
129
134 if (this->_p != rhs._p) {
135 std::swap(this->_p, rhs._p);
136 }
137
138 return *this;
139 }
140
144 IntrusivePointer& operator=(T* p) noexcept {
145 if (this->_p != p) {
146 // addReference the new pointer before releaseReference'ing the old.
147 T* pOld = this->_p;
148 this->_p = p;
149 addReference();
150
151 if (pOld) {
152 pOld->releaseReference();
153 }
154 }
155
156 return *this;
157 }
158
162 T& operator*() const noexcept { return *this->_p; }
163
167 T* operator->() const noexcept { return this->_p; }
168
173 explicit operator bool() const noexcept { return this->_p != nullptr; }
174
178 T* get() const noexcept { return this->_p; }
179
183 bool operator==(const IntrusivePointer<T>& rhs) const noexcept {
184 return this->_p == rhs._p;
185 }
186
188 template <class U>
189 bool operator==(const IntrusivePointer<U>& rhs) const noexcept {
190 return this->_p == rhs._p;
191 }
192
196 bool operator!=(const IntrusivePointer<T>& rhs) const noexcept {
197 return !(*this == rhs);
198 }
199
204 bool operator==(const T* pRhs) const noexcept { return this->_p == pRhs; }
205
210 bool operator!=(const T* pRhs) const noexcept { return !(*this == pRhs); }
211
212private:
213 void addReference() noexcept {
214 if (this->_p) {
215 this->_p->addReference();
216 }
217 }
218
219 void releaseReference() noexcept {
220 if (this->_p) {
221 this->_p->releaseReference();
222 }
223 }
224
225 T* _p;
226 template <typename U> friend class IntrusivePointer;
227};
228
235template <typename T, typename U>
236IntrusivePointer<T>
238 return IntrusivePointer<T>(const_cast<T*>(p.get()));
239}
240
241} // 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.
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.