DNA Calib 1.1
Project brief
ScopedPtr.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#ifdef _MSC_VER
6 #pragma warning(push)
7 #pragma warning(disable : 4365 4987)
8#endif
9#include <utility>
10#ifdef _MSC_VER
11 #pragma warning(pop)
12#endif
13
14namespace pma {
15
16template<class T, class B = T>
17struct New {
18 template<typename ... Args>
19 B* operator()(Args&& ... args) {
20 return new T{std::forward<Args>(args)...};
21 }
22
23};
24
25template<class T, class B = T>
26struct Delete {
27 void operator()(B* ptr) {
28 // Calling delete on an incomplete type is undefined behavior.
29 // This check will result in a compile error for incomplete types, rather than allow UB.
30 #if !defined(__clang__) && defined(__GNUC__)
31 #pragma GCC diagnostic push
32 #pragma GCC diagnostic ignored "-Wsign-conversion"
33 #endif
34 using complete_type_checker = char[sizeof(T) ? 1 : -1];
35 #if !defined(__clang__) && defined(__GNUC__)
36 #pragma GCC diagnostic pop
37 #endif
38 static_cast<void>(sizeof(complete_type_checker));
39 delete ptr;
40 }
41
42};
43
44template<class T>
45struct New<T[]> {
46 T* operator()(std::size_t size) {
47 return new T[size]{};
48 }
49
50};
51
52template<class T>
53struct Delete<T[]> {
54 void operator()(T* ptr) {
55 // Calling delete on an incomplete type is undefined behavior.
56 // This check will result in a compile error for incomplete types, rather than allow UB.
57 #if !defined(__clang__) && defined(__GNUC__)
58 #pragma GCC diagnostic push
59 #pragma GCC diagnostic ignored "-Wsign-conversion"
60 #endif
61 using complete_type_checker = char[sizeof(T) ? 1 : -1];
62 #if !defined(__clang__) && defined(__GNUC__)
63 #pragma GCC diagnostic pop
64 #endif
65 static_cast<void>(sizeof(complete_type_checker));
66 delete[] ptr;
67 }
68
69};
70
71template<class T, class B = T>
73 template<typename ... Args>
74 B* operator()(Args&& ... args) {
75 return T::create(std::forward<Args>(args)...);
76 }
77
78};
79
80template<class T, class B = T>
82 void operator()(B* ptr) {
83 T::destroy(static_cast<T*>(ptr));
84 }
85
86};
87
88template<class T>
90 using type = New<T>;
91};
92
93template<class T>
95 using type = Delete<T>;
96};
97
115template<class T, class TDestroyer = typename DefaultInstanceDestroyer<T>::type>
116class ScopedPtr : private TDestroyer {
117 private:
118 template<typename U>
119 struct inspect {
120 using element_type = U;
122 using is_array = std::false_type;
123 };
124
125 template<typename U>
126 struct inspect<U[]> {
127 using element_type = U;
129 using is_array = std::true_type;
130 };
131
132 public:
135 using destroyer_type = TDestroyer;
136
137 template<typename U, class UDestroyer>
138 friend class ScopedPtr;
139
140 public:
141 ScopedPtr() : ptr{nullptr} {
142 }
143
144 explicit ScopedPtr(pointer ptr_) : ptr{ptr_} {
145 }
146
147 ScopedPtr(pointer ptr_, destroyer_type&& destroyer) : destroyer_type{std::move(destroyer)}, ptr{ptr_} {
148 }
149
151 if (ptr) {
152 destroyer_type::operator()(ptr);
153 ptr = pointer{};
154 }
155 }
156
157 ScopedPtr(std::nullptr_t) : ptr{nullptr} {
158 }
159
160 ScopedPtr& operator=(std::nullptr_t) {
161 reset();
162 return *this;
163 }
164
165 ScopedPtr(const ScopedPtr&) = delete;
166 ScopedPtr& operator=(const ScopedPtr&) = delete;
167
168 ScopedPtr(ScopedPtr&& rhs) noexcept : ptr{nullptr} {
169 rhs.swap(*this);
170 }
171
172 ScopedPtr& operator=(ScopedPtr&& rhs) noexcept {
173 rhs.swap(*this);
174 return *this;
175 }
176
177 template<typename U, class UDestroyer>
178 ScopedPtr(ScopedPtr<U, UDestroyer>&& rhs) noexcept : ptr{nullptr} {
179 ScopedPtr<T, destroyer_type> tmp{rhs.release(), static_cast<UDestroyer &&>(rhs)};
180 tmp.swap(*this);
181 }
182
183 template<typename U, class UDestroyer>
185 ScopedPtr<T, destroyer_type> tmp{rhs.release(), static_cast<UDestroyer &&>(rhs)};
186 tmp.swap(*this);
187 return *this;
188 }
189
190 template<typename U = T, typename IA = typename inspect<U>::is_array>
191 typename std::enable_if<IA::value, element_type&>::type operator[](std::size_t index) const noexcept {
192 return ptr[index];
193 }
194
195 template<typename U = T, typename IA = typename inspect<U>::is_array>
196 typename std::enable_if<!IA::value, element_type&>::type operator*() const noexcept {
197 return *ptr;
198 }
199
200 pointer operator->() const noexcept {
201 return ptr;
202 }
203
204 operator bool() const noexcept {
205 return ptr != nullptr;
206 }
207
208 pointer get() const noexcept {
209 return ptr;
210 }
211
212 pointer release() noexcept {
213 pointer result = nullptr;
214 std::swap(result, ptr);
215 return result;
216 }
217
218 void reset(pointer rhs = pointer()) noexcept {
219 pointer old = release();
220 ptr = rhs;
221 if (old) {
222 destroyer_type::operator()(old);
223 }
224 }
225
226 void swap(ScopedPtr& rhs) noexcept {
227 std::swap(static_cast<destroyer_type&>(*this), static_cast<destroyer_type&>(rhs));
228 std::swap(ptr, rhs.ptr);
229 }
230
231 private:
233};
234
250template<class T, class TCreator, class TDestroyer, typename ... Args,
251 typename Base = typename std::remove_pointer < decltype(TCreator{} (std::declval<Args>()...)) > ::type>
253 static_assert(std::is_same<Base, T>::value ||
254 std::is_base_of<Base, T>::value ||
255 std::is_convertible<T, typename std::add_pointer<Base>::type>::value,
256 "Incompatible types.");
257 return ScopedPtr<Base, TDestroyer>{TCreator{} (std::forward<Args>(args)...)};
258}
259
260template<class T, template<class ...> class TCreatorTemplate, template<class ...> class TDestroyerTemplate, typename ... Args>
262 using TCreator = TCreatorTemplate<T>;
263 using TDestroyer = TDestroyerTemplate<T>;
264 return makeScoped<T, TCreator, TDestroyer>(std::forward<Args>(args)...);
265}
266
267template<class T, typename ... Args>
269 using TCreator = typename DefaultInstanceCreator<T>::type;
270 using TDestroyer = typename DefaultInstanceDestroyer<T>::type;
271 return makeScoped<T, TCreator, TDestroyer>(std::forward<Args>(args)...);
272}
273
274} // namespace pma
Takes ownership over the given pointer and handles it's lifetime.
Definition: ScopedPtr.h:116
ScopedPtr()
Definition: ScopedPtr.h:141
std::enable_if< IA::value, element_type & >::type operator[](std::size_t index) const noexcept
Definition: ScopedPtr.h:191
ScopedPtr & operator=(ScopedPtr &&rhs) noexcept
Definition: ScopedPtr.h:172
TDestroyer destroyer_type
Definition: ScopedPtr.h:135
pointer operator->() const noexcept
Definition: ScopedPtr.h:200
typename inspect< T >::pointer_type pointer
Definition: ScopedPtr.h:133
pointer get() const noexcept
Definition: ScopedPtr.h:208
~ScopedPtr()
Definition: ScopedPtr.h:150
void swap(ScopedPtr &rhs) noexcept
Definition: ScopedPtr.h:226
ScopedPtr & operator=(const ScopedPtr &)=delete
pointer ptr
Definition: ScopedPtr.h:232
ScopedPtr(std::nullptr_t)
Definition: ScopedPtr.h:157
typename inspect< T >::element_type element_type
Definition: ScopedPtr.h:134
ScopedPtr & operator=(std::nullptr_t)
Definition: ScopedPtr.h:160
void reset(pointer rhs=pointer()) noexcept
Definition: ScopedPtr.h:218
pointer release() noexcept
Definition: ScopedPtr.h:212
ScopedPtr & operator=(ScopedPtr< U, UDestroyer > &&rhs) noexcept
Definition: ScopedPtr.h:184
ScopedPtr(const ScopedPtr &)=delete
ScopedPtr(pointer ptr_, destroyer_type &&destroyer)
Definition: ScopedPtr.h:147
ScopedPtr(ScopedPtr &&rhs) noexcept
Definition: ScopedPtr.h:168
ScopedPtr(pointer ptr_)
Definition: ScopedPtr.h:144
std::enable_if<!IA::value, element_type & >::type operator*() const noexcept
Definition: ScopedPtr.h:196
ScopedPtr(ScopedPtr< U, UDestroyer > &&rhs) noexcept
Definition: ScopedPtr.h:178
Definition: BinaryStreamReader.h:121
ScopedPtr< Base, TDestroyer > makeScoped(Args &&... args)
Syntactic sugar for creating instances wrapped in a ScopedPtr.
Definition: ScopedPtr.h:252
Definition: ScopedPtr.h:89
Definition: ScopedPtr.h:94
void operator()(T *ptr)
Definition: ScopedPtr.h:54
Definition: ScopedPtr.h:26
void operator()(B *ptr)
Definition: ScopedPtr.h:27
Definition: ScopedPtr.h:72
B * operator()(Args &&... args)
Definition: ScopedPtr.h:74
Definition: ScopedPtr.h:81
void operator()(B *ptr)
Definition: ScopedPtr.h:82
T * operator()(std::size_t size)
Definition: ScopedPtr.h:46
Definition: ScopedPtr.h:17
B * operator()(Args &&... args)
Definition: ScopedPtr.h:19
element_type * pointer_type
Definition: ScopedPtr.h:128
U element_type
Definition: ScopedPtr.h:127
std::true_type is_array
Definition: ScopedPtr.h:129
Definition: ScopedPtr.h:119
std::false_type is_array
Definition: ScopedPtr.h:122
element_type * pointer_type
Definition: ScopedPtr.h:121
U element_type
Definition: ScopedPtr.h:120