100 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
	
| #pragma once
 | |
| 
 | |
| #include <BAN/Errors.h>
 | |
| #include <BAN/NoCopyMove.h>
 | |
| 
 | |
| namespace BAN
 | |
| {
 | |
| 
 | |
| 	template<typename T>
 | |
| 	class UniqPtr
 | |
| 	{
 | |
| 		BAN_NON_COPYABLE(UniqPtr);
 | |
| 
 | |
| 	public:
 | |
| 		UniqPtr() = default;
 | |
| 
 | |
| 		template<typename U>
 | |
| 		UniqPtr(UniqPtr<U>&& other)
 | |
| 		{
 | |
| 			m_pointer = other.m_pointer;
 | |
| 			other.m_pointer = nullptr;
 | |
| 		}
 | |
| 
 | |
| 		~UniqPtr()
 | |
| 		{
 | |
| 			clear();
 | |
| 		}
 | |
| 
 | |
| 		static UniqPtr adopt(T* pointer)
 | |
| 		{
 | |
| 			UniqPtr uniq;
 | |
| 			uniq.m_pointer = pointer;
 | |
| 			return uniq;
 | |
| 		}
 | |
| 
 | |
| 		// NOTE: don't use is_constructible_v<T, Args...> as UniqPtr<T> is allowed with friends
 | |
| 		template<typename... Args>
 | |
| 		static BAN::ErrorOr<UniqPtr> create(Args&&... args) requires requires(Args&&... args) { T(forward<Args>(args)...); }
 | |
| 		{
 | |
| 			UniqPtr uniq;
 | |
| 			uniq.m_pointer = new T(BAN::forward<Args>(args)...);
 | |
| 			if (uniq.m_pointer == nullptr)
 | |
| 				return BAN::Error::from_errno(ENOMEM);
 | |
| 			return uniq;
 | |
| 		}
 | |
| 
 | |
| 		template<typename U>
 | |
| 		UniqPtr& operator=(UniqPtr<U>&& other)
 | |
| 		{
 | |
| 			clear();
 | |
| 			m_pointer = other.m_pointer;
 | |
| 			other.m_pointer = nullptr;
 | |
| 			return *this;
 | |
| 		}
 | |
| 
 | |
| 		T& operator*()
 | |
| 		{
 | |
| 			ASSERT(m_pointer);
 | |
| 			return *m_pointer;
 | |
| 		}
 | |
| 
 | |
| 		const T& operator*() const
 | |
| 		{
 | |
| 			ASSERT(m_pointer);
 | |
| 			return *m_pointer;
 | |
| 		}
 | |
| 
 | |
| 		T* operator->()
 | |
| 		{
 | |
| 			ASSERT(m_pointer);
 | |
| 			return m_pointer;
 | |
| 		}
 | |
| 
 | |
| 		const T* operator->() const
 | |
| 		{
 | |
| 			ASSERT(m_pointer);
 | |
| 			return m_pointer;
 | |
| 		}
 | |
| 
 | |
| 		T* ptr() { return m_pointer; }
 | |
| 		const T* ptr() const { return m_pointer; }
 | |
| 
 | |
| 		void clear()
 | |
| 		{
 | |
| 			if (m_pointer)
 | |
| 				delete m_pointer;
 | |
| 			m_pointer = nullptr;
 | |
| 		}
 | |
| 
 | |
| 		operator bool() const { return m_pointer != nullptr; }
 | |
| 
 | |
| 	private:
 | |
| 		T* m_pointer = nullptr;
 | |
| 
 | |
| 		template<typename U>
 | |
| 		friend class UniqPtr;
 | |
| 	};
 | |
| 
 | |
| }
 |