This repository has been archived by the owner on May 17, 2021. It is now read-only.
forked from higan-emu/higan
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathunique-pointer.hpp
106 lines (82 loc) · 2.51 KB
/
unique-pointer.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#pragma once
namespace nall {
template<typename T>
struct unique_pointer {
template<typename... P> static auto create(P&&... p) {
return unique_pointer<T>{new T{forward<P>(p)...}};
}
using type = T;
T* pointer = nullptr;
function<void (T*)> deleter;
unique_pointer(const unique_pointer&) = delete;
auto operator=(const unique_pointer&) -> unique_pointer& = delete;
unique_pointer(T* pointer = nullptr, const function<void (T*)>& deleter = {}) : pointer(pointer), deleter(deleter) {}
~unique_pointer() { reset(); }
auto operator=(T* source) -> unique_pointer& {
reset();
pointer = source;
return *this;
}
explicit operator bool() const { return pointer; }
auto operator->() -> T* { return pointer; }
auto operator->() const -> const T* { return pointer; }
auto operator*() -> T& { return *pointer; }
auto operator*() const -> const T& { return *pointer; }
auto operator()() -> T& { return *pointer; }
auto operator()() const -> const T& { return *pointer; }
auto data() -> T* { return pointer; }
auto data() const -> const T* { return pointer; }
auto release() -> T* {
auto result = pointer;
pointer = nullptr;
return result;
}
auto reset() -> void {
if(pointer) {
if(deleter) {
deleter(pointer);
} else {
delete pointer;
}
pointer = nullptr;
}
}
};
template<typename T>
struct unique_pointer<T[]> {
using type = T;
T* pointer = nullptr;
function<auto (T*) -> void> deleter;
unique_pointer(const unique_pointer&) = delete;
auto operator=(const unique_pointer&) -> unique_pointer& = delete;
unique_pointer(T* pointer = nullptr, const function<void (T*)>& deleter = {}) : pointer(pointer), deleter(deleter) {}
~unique_pointer() { reset(); }
auto operator=(T* source) -> unique_pointer& {
reset();
pointer = source;
return *this;
}
explicit operator bool() const { return pointer; }
auto operator()() -> T* { return pointer; }
auto operator()() const -> T* { return pointer; }
auto operator[](uint offset) -> T& { return pointer[offset]; }
auto operator[](uint offset) const -> const T& { return pointer[offset]; }
auto data() -> T* { return pointer; }
auto data() const -> const T* { return pointer; }
auto release() -> T* {
auto result = pointer;
pointer = nullptr;
return result;
}
auto reset() -> void {
if(pointer) {
if(deleter) {
deleter(pointer);
} else {
delete[] pointer;
}
pointer = nullptr;
}
}
};
}