-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunique_ptr_array.h
138 lines (117 loc) · 2.67 KB
/
unique_ptr_array.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#pragma once
/**
* @file unique_ptr_array.h
* @description
* @copyright
* @author Levon Ghukasyan
*/
template <typename T, class Deleter>
class unique_ptr<T[], Deleter>
{
public:
using pointer_type = T*;
using value_type = T;
/// @brief constructors and description
/// @{
public:
constexpr unique_ptr() noexcept
: m_pointer(pointer_type())
, m_deleter(Deleter())
{
}
explicit unique_ptr(pointer_type ptr) noexcept
: m_pointer(ptr)
, m_deleter(Deleter())
{
}
unique_ptr(pointer_type ptr, const Deleter& del) noexcept
: m_deleter(del)
, m_pointer(ptr)
{
}
unique_ptr(unique_ptr&& ptr) noexcept
: m_deleter(std::forward<Deleter>(ptr.get_deleter()))
, m_pointer(ptr.release())
{
}
template <class U, class E>
unique_ptr(unique_ptr<U, E>&& u_ptr) noexcept
: m_deleter(std::forward<Deleter>(u_ptr.get_deleter()))
, m_pointer(u_ptr.release())
{
}
~unique_ptr() noexcept
{
reset();
}
/// @}
/// @brief assignment operators
/// @{
public:
unique_ptr& operator= (unique_ptr&& r) noexcept
{
reset(r.release());
get_deleter() = std::move(r.get_deleter());
return *this;
}
template<class U, class E>
unique_ptr& operator= (unique_ptr<U, E>&& r)
{
reset(r.release());
get_deleter() = std::move(r.get_deleter());
return *this;
}
unique_ptr& operator= (std::nullptr_t)
{
reset();
return *this;
}
unique_ptr(const unique_ptr& other) = delete;
template <class U, class E>
unique_ptr(const unique_ptr<U, E>& other) = delete;
template <class U, class E>
unique_ptr& operator= (const unique_ptr<U, E>& other) = delete;
/// @}
/// @brief
/// @{
public:
value_type operator[] (size_t idx) const
{
return get()[idx];
}
pointer_type get() const noexcept
{
return m_pointer;
}
Deleter get_deleter() noexcept
{
return m_deleter;
}
const Deleter& get_deleter() const noexcept
{
return m_deleter;
}
inline pointer_type release() noexcept
{
pointer_type ptr = get();
m_pointer = nullptr;
return ptr;
}
/// @}
public:
void reset(pointer_type ptr = pointer_type())
{
if (ptr != get()) {
get_deleter()(get());
m_pointer = ptr;
}
}
void swap(unique_ptr&& ptr)
{
std::swap(m_pointer, ptr.m_pointer);
std::swap(m_deleter, ptr.m_deleter);
}
private:
pointer_type m_pointer;
Deleter m_deleter;
};