Grindstone Game Engine v0.2.0
An open source game engine and toolkit.
Loading...
Searching...
No Matches
UniquePtr.hpp
1#pragma once
2
3#include <functional>
4
5namespace Grindstone {
6 template<typename T>
7 class UniquePtr {
8 public:
9
10 UniquePtr() : ptr(nullptr), deleteFn() {}
11
12 explicit UniquePtr(T* ptr, std::function<void(void*)> newDeleteFn) : ptr(ptr), deleteFn(newDeleteFn) {}
13
14 UniquePtr(std::nullptr_t) : ptr(nullptr), deleteFn() {}
15
16 // Deleted Copy operations
17 UniquePtr(const UniquePtr<T>& other) = delete;
18 UniquePtr& operator=(const UniquePtr<T>& other) = delete;
19
20 UniquePtr& operator=(std::nullptr_t) {
21 Release();
22 return *this;
23 }
24
25 UniquePtr(UniquePtr&& other) noexcept
26 : ptr(other.ptr), deleteFn(std::move(other.deleteFn)) {
27 other.ptr = nullptr;
28 other.deleteFn = std::function<void(void*)>{};
29
30 }
31
32 UniquePtr& operator=(UniquePtr&& other) noexcept {
33 UniquePtr tmp(std::move(other));
34 Swap(tmp);
35 return *this;
36 }
37
38 template<typename U,
39 std::enable_if_t<std::is_convertible_v<U*, T*>, int> = 0>
40 UniquePtr(UniquePtr<U>&& other) noexcept
41 : ptr(other.Release()), deleteFn(std::move(other.GetDeleter())) {}
42
43 template<typename U,
44 std::enable_if_t<std::is_convertible_v<U*, T*>, int> = 0>
45 UniquePtr& operator=(UniquePtr<U>&& other) noexcept {
46 if (this != reinterpret_cast<UniquePtr<T>*>(&other)) {
47 Reset();
48 ptr = other.Release();
49 deleteFn = std::move(other.GetDeleter());
50 }
51 return *this;
52 }
53
54 T* Release() noexcept {
55 T* emptyPtr = nullptr;
56 std::swap(emptyPtr, ptr);
57 deleteFn = std::function<void(void*)>{};
58
59 return emptyPtr;
60 }
61
62 void Reset() noexcept {
63 if (ptr != nullptr) {
64 ptr->~T();
65
66 if (deleteFn) {
67 deleteFn(ptr);
68 }
69
70 ptr = nullptr;
71 }
72
73 deleteFn = std::function<void(void*)>{};
74 }
75
76 void Swap(UniquePtr& other) noexcept {
77 std::swap(ptr, other.ptr);
78 std::swap(deleteFn, other.deleteFn);
79 }
80
81 bool operator==(const Grindstone::UniquePtr<T>& other) const noexcept {
82 return ptr == other.ptr && deleteFn == other.deleteFn;
83 }
84
85 bool operator==(const T* other) const noexcept {
86 return ptr == other;
87 }
88
89 bool operator==(std::nullptr_t) const noexcept {
90 return ptr == nullptr;
91 }
92
93 explicit operator T*() const {
94 return ptr;
95 }
96
97 explicit operator bool() const {
98 return ptr != nullptr;
99 }
100
101 T* operator->() {
102 return this->ptr;
103 }
104
105 const T* operator->() const {
106 return this->ptr;
107 }
108
109 T& operator*() {
110 return *(this->ptr);
111 }
112
113 const T& operator*() const {
114 return *(this->ptr);
115 }
116
117 T* Get() {
118 return this->ptr;
119 }
120
121 const T* Get() const {
122 return this->ptr;
123 }
124
125 const std::function<void(void*)>& GetDeleter() const {
126 return this->deleteFn;
127 }
128
129 ~UniquePtr() {
130 Reset();
131 }
132
133 template<typename U>
134 bool operator==(const UniquePtr<U>& other) const noexcept {
135 static_assert(std::is_convertible_v<U*, T*> || std::is_convertible_v<T*, U*>,
136 "UniquePtr comparison requires compatible pointer types.");
137 return ptr == other.ptr && deleteFn == other.deleteFn;
138 }
139
140 private:
141 T* ptr = nullptr;
142 std::function<void(void*)> deleteFn;
143 };
144}
Definition UniquePtr.hpp:7