| 
									
										
										
										
											2019-09-20 15:19:11 +02:00
										 |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <AK/StdLibExtras.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This is a stopgap pointer. It's not meant to stick around forever.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<typename T> | 
					
						
							|  |  |  | class ObjectPtr { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     ObjectPtr() {} | 
					
						
							| 
									
										
										
										
											2019-09-21 12:03:22 +02:00
										 |  |  |     ObjectPtr(T* ptr) | 
					
						
							|  |  |  |         : m_ptr(ptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ObjectPtr(T& ptr) | 
					
						
							|  |  |  |         : m_ptr(&ptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-20 15:19:11 +02:00
										 |  |  |     ~ObjectPtr() | 
					
						
							| 
									
										
										
										
											2019-09-21 18:07:46 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         clear(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void clear() | 
					
						
							| 
									
										
										
										
											2019-09-20 15:19:11 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         if (m_ptr && !m_ptr->parent()) | 
					
						
							|  |  |  |             delete m_ptr; | 
					
						
							| 
									
										
										
										
											2019-09-21 18:07:46 +02:00
										 |  |  |         m_ptr = nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ObjectPtr& operator=(std::nullptr_t) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         clear(); | 
					
						
							|  |  |  |         return *this; | 
					
						
							| 
									
										
										
										
											2019-09-20 15:19:11 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-21 12:03:22 +02:00
										 |  |  |     template<typename U> | 
					
						
							|  |  |  |     ObjectPtr(U* ptr) | 
					
						
							|  |  |  |         : m_ptr(static_cast<T*>(ptr)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-20 15:19:11 +02:00
										 |  |  |     ObjectPtr(const ObjectPtr& other) | 
					
						
							|  |  |  |         : m_ptr(other.m_ptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-21 12:03:22 +02:00
										 |  |  |     template<typename U> | 
					
						
							|  |  |  |     ObjectPtr(const ObjectPtr<U>& other) | 
					
						
							|  |  |  |         : m_ptr(static_cast<T*>(const_cast<ObjectPtr<U>&>(other).ptr())) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-20 15:19:11 +02:00
										 |  |  |     ObjectPtr(ObjectPtr&& other) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-09-21 12:03:22 +02:00
										 |  |  |         m_ptr = other.leak_ptr(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<typename U> | 
					
						
							|  |  |  |     ObjectPtr(const ObjectPtr<U>&& other) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_ptr = static_cast<T*>(const_cast<ObjectPtr<U>&>(other).leak_ptr()); | 
					
						
							| 
									
										
										
										
											2019-09-20 15:19:11 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ObjectPtr& operator=(const ObjectPtr& other) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-09-21 18:07:46 +02:00
										 |  |  |         if (this != &other) { | 
					
						
							|  |  |  |             clear(); | 
					
						
							|  |  |  |             m_ptr = other.m_ptr; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-09-20 15:19:11 +02:00
										 |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ObjectPtr& operator=(ObjectPtr&& other) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (this != &other) { | 
					
						
							| 
									
										
										
										
											2019-09-21 18:07:46 +02:00
										 |  |  |             clear(); | 
					
						
							| 
									
										
										
										
											2019-09-20 15:19:11 +02:00
										 |  |  |             m_ptr = exchange(other.m_ptr, nullptr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     T* operator->() { return m_ptr; } | 
					
						
							|  |  |  |     const T* operator->() const { return m_ptr; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     operator T*() { return m_ptr; } | 
					
						
							|  |  |  |     operator const T*() const { return m_ptr; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     T& operator*() { return *m_ptr; } | 
					
						
							|  |  |  |     const T& operator*() const { return *m_ptr; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-21 12:03:22 +02:00
										 |  |  |     T* ptr() const { return m_ptr; } | 
					
						
							|  |  |  |     T* leak_ptr() { return exchange(m_ptr, nullptr); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-21 17:32:26 +02:00
										 |  |  |     operator bool() const { return !!m_ptr; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-20 15:19:11 +02:00
										 |  |  | private: | 
					
						
							|  |  |  |     T* m_ptr { nullptr }; | 
					
						
							|  |  |  | }; |