-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUniquePtr.h
123 lines (103 loc) · 2.89 KB
/
UniquePtr.h
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef UNIQUEPTR_H
#define UNIQUEPTR_H
#include <cstddef>
#include <utility>
#include <functional>
struct DefaultDeleter {
template <typename T>
inline void operator()(T *p) const {
delete p;
}
};
template <typename T, typename D> class UniquePtr;
template <typename T, typename D> void swap(UniquePtr<T, D> &, UniquePtr<T, D> &);
template <typename T, typename Deleter = DefaultDeleter>
class UniquePtr {
friend void swap<T, Deleter>(UniquePtr<T, Deleter> &, UniquePtr<T, Deleter> &);
public:
using element_type = T;
using deleter_type = Deleter;
UniquePtr() : element(nullptr), del(Deleter()) {}
UniquePtr(Deleter d) : element(nullptr), del(d) {}
UniquePtr(T *p) : element(p), del(Deleter()) {}
UniquePtr(T *p, Deleter d) : element(p), del(d) {}
UniquePtr(const UniquePtr &) = delete;
UniquePtr(UniquePtr &&u) noexcept : element(u.element), del(std::move(u.del)) {
u.element = nullptr;
}
UniquePtr &operator=(const UniquePtr &) = delete;
UniquePtr &operator=(UniquePtr &&rhs) noexcept {
if (this != &rhs) {
del(element);
element = rhs.element;
del = std::move(rhs.del);
rhs.element = nullptr;
}
return *this;
}
~UniquePtr() {
if (element)
del(element);
}
T *get() { return element; }
const T *get() const { return element; }
void swap(UniquePtr &u) {
::swap(*this, u);
}
T *release() {
T *ret = element;
element = nullptr;
return ret;
}
void reset() {
del(element);
element = nullptr;
}
void reset(T *p) {
del(element);
element = p;
}
void reset(std::nullptr_t) {
del(element);
element = nullptr;
}
T &operator*() { return *element; }
const T &operator*() const { return *element; }
T *operator->() { return &this->operator*(); }
const T *operator->() const { return &this->operator*(); }
explicit operator bool() const { return element; }
private:
T *element;
Deleter del;
};
template <typename T, typename Deleter>
inline void swap(UniquePtr<T, Deleter> &lhs, UniquePtr<T, Deleter> &rhs) {
using std::swap;
swap(lhs.element, rhs.element);
swap(lhs.del, rhs.del);
}
template <typename T, typename D>
inline bool operator==(const UniquePtr<T, D> &lhs, const UniquePtr<T, D> &rhs) {
return lhs.get() == rhs.get();
}
template <typename T, typename D>
inline bool operator!=(const UniquePtr<T, D> &lhs, const UniquePtr<T, D> &rhs) {
return !(lhs == rhs);
}
template <typename T, typename D>
inline bool operator<(const UniquePtr<T, D> &lhs, const UniquePtr<T, D> &rhs) {
return std::less<const T *>()(lhs.get(), rhs.get());
}
template <typename T, typename D>
inline bool operator>(const UniquePtr<T, D> &lhs, const UniquePtr<T, D> &rhs) {
return (rhs < lhs);
}
template <typename T, typename D>
inline bool operator<=(const UniquePtr<T, D> &lhs, const UniquePtr<T, D> &rhs) {
return !(rhs < lhs);
}
template <typename T, typename D>
inline bool operator>=(const UniquePtr<T, D> &lhs, const UniquePtr<T, D> &rhs) {
return !(lhs < rhs);
}
#endif