FastLED 3.9.15
Loading...
Searching...
No Matches
unique_ptr.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/namespace.h"
4#include "fl/type_traits.h"
5#include "fl/utility.h" // for fl::move, fl::forward, fl::swap
6#include "fl/stdint.h" // for fl::size_t
7#include "fl/cstddef.h" // for fl::nullptr_t
8#include "fl/initializer_list.h" // for consistency (though not used in unique_ptr itself)
9
10namespace fl {
11
12template<typename T>
14 void operator()(T* ptr) const {
15 delete ptr;
16 }
17
18 // Allow conversion from derived to base type deleters
19 template<typename U>
21
22 default_delete() = default;
23};
24
25template<typename T>
26struct default_delete<T[]> {
27 void operator()(T* ptr) const {
28 delete[] ptr;
29 }
30};
31
32template<typename T, typename Deleter = default_delete<T>>
34public:
35 using element_type = T;
36 using deleter_type = Deleter;
37 using pointer = T*;
38
39private:
41 Deleter deleter_;
42
43public:
44 // Constructors
45 constexpr unique_ptr() noexcept : ptr_(nullptr), deleter_() {}
46 constexpr unique_ptr(fl::nullptr_t) noexcept : ptr_(nullptr), deleter_() {}
47 explicit unique_ptr(pointer p) noexcept : ptr_(p), deleter_() {}
48 unique_ptr(pointer p, const Deleter& d) noexcept : ptr_(p), deleter_(d) {}
49 unique_ptr(pointer p, Deleter&& d) noexcept : ptr_(p), deleter_(fl::move(d)) {}
50
51 // Move constructor
52 unique_ptr(unique_ptr&& u) noexcept : ptr_(u.release()), deleter_(fl::move(u.deleter_)) {}
53
54 // Converting move constructor
55 template<typename U, typename E>
57 : ptr_(u.release()), deleter_(fl::move(u.get_deleter())) {}
58
59 // Copy semantics deleted
60 unique_ptr(const unique_ptr&) = delete;
61 unique_ptr& operator=(const unique_ptr&) = delete;
62
63 // Move assignment
65 if (this != &u) {
66 reset(u.release());
67 deleter_ = fl::move(u.deleter_);
68 }
69 return *this;
70 }
71
72 // Converting move assignment
73 template<typename U, typename E>
75 reset(u.release());
76 deleter_ = fl::move(u.get_deleter());
77 return *this;
78 }
79
80 // nullptr assignment
82 reset();
83 return *this;
84 }
85
86 // Destructor
88 if (ptr_) {
90 }
91 }
92
93 // Observers
94 pointer get() const noexcept { return ptr_; }
95 Deleter& get_deleter() noexcept { return deleter_; }
96 const Deleter& get_deleter() const noexcept { return deleter_; }
97 explicit operator bool() const noexcept { return ptr_ != nullptr; }
98
99 // Access
100 T& operator*() const { return *ptr_; }
101 pointer operator->() const noexcept { return ptr_; }
102
103 // Modifiers
104 pointer release() noexcept {
105 pointer tmp = ptr_;
106 ptr_ = nullptr;
107 return tmp;
108 }
109
110 void reset(pointer p = nullptr) noexcept {
111 pointer old_ptr = ptr_;
112 ptr_ = p;
113 if (old_ptr) {
114 deleter_(old_ptr);
115 }
116 }
117
118 void swap(unique_ptr& u) noexcept {
119 using fl::swap;
120 swap(ptr_, u.ptr_);
121 swap(deleter_, u.deleter_);
122 }
123};
124
125// Array specialization for scoped_array consolidation
126template<typename T, typename Deleter>
127class unique_ptr<T[], Deleter> {
128public:
129 using element_type = T;
130 using deleter_type = Deleter;
131 using pointer = T*;
132
133private:
135 Deleter deleter_;
136
137public:
138 // Constructors
139 constexpr unique_ptr() noexcept : ptr_(nullptr), deleter_() {}
140 constexpr unique_ptr(fl::nullptr_t) noexcept : ptr_(nullptr), deleter_() {}
141 explicit unique_ptr(pointer p) noexcept : ptr_(p), deleter_() {}
142 unique_ptr(pointer p, const Deleter& d) noexcept : ptr_(p), deleter_(d) {}
143 unique_ptr(pointer p, Deleter&& d) noexcept : ptr_(p), deleter_(fl::move(d)) {}
144
145 // Move constructor
146 unique_ptr(unique_ptr&& u) noexcept : ptr_(u.release()), deleter_(fl::move(u.deleter_)) {}
147
148 // Converting move constructor
149 template<typename U, typename E>
151 : ptr_(u.release()), deleter_(fl::move(u.get_deleter())) {}
152
153 // Copy semantics deleted
154 unique_ptr(const unique_ptr&) = delete;
155 unique_ptr& operator=(const unique_ptr&) = delete;
156
157 // Move assignment
159 if (this != &u) {
160 reset(u.release());
161 deleter_ = fl::move(u.deleter_);
162 }
163 return *this;
164 }
165
166 // Converting move assignment
167 template<typename U, typename E>
169 reset(u.release());
170 deleter_ = fl::move(u.get_deleter());
171 return *this;
172 }
173
174 // nullptr assignment
176 reset();
177 return *this;
178 }
179
180 // Destructor
182 if (ptr_) {
183 deleter_(ptr_);
184 }
185 }
186
187 // Observers
188 pointer get() const noexcept { return ptr_; }
189 Deleter& get_deleter() noexcept { return deleter_; }
190 const Deleter& get_deleter() const noexcept { return deleter_; }
191 explicit operator bool() const noexcept { return ptr_ != nullptr; }
192
193 // Array access (replaces scoped_array functionality)
194 T& operator[](fl::size_t i) const { return ptr_[i]; }
195
196 // Modifiers
197 pointer release() noexcept {
198 pointer tmp = ptr_;
199 ptr_ = nullptr;
200 return tmp;
201 }
202
203 void reset(pointer p = nullptr) noexcept {
204 pointer old_ptr = ptr_;
205 ptr_ = p;
206 if (old_ptr) {
207 deleter_(old_ptr);
208 }
209 }
210
211 void swap(unique_ptr& u) noexcept {
212 using fl::swap;
213 swap(ptr_, u.ptr_);
214 swap(deleter_, u.deleter_);
215 }
216};
217
218// Non-member functions using FL equivalents
219template<typename T, typename Deleter>
221 lhs.swap(rhs);
222}
223
224// Comparison operators using FL equivalents
225template<typename T1, typename Deleter1, typename T2, typename Deleter2>
227 return lhs.get() == rhs.get();
228}
229
230template<typename T1, typename Deleter1, typename T2, typename Deleter2>
232 return !(lhs == rhs);
233}
234
235template<typename T, typename Deleter>
237 return !ptr;
238}
239
240template<typename T, typename Deleter>
242 return !ptr;
243}
244
245template<typename T, typename Deleter>
247 return static_cast<bool>(ptr);
248}
249
250template<typename T, typename Deleter>
252 return static_cast<bool>(ptr);
253}
254
255} // namespace fl
void swap(unique_ptr &u) noexcept
Definition unique_ptr.h:211
T & operator[](fl::size_t i) const
Definition unique_ptr.h:194
unique_ptr(unique_ptr &&u) noexcept
Definition unique_ptr.h:146
unique_ptr & operator=(unique_ptr &&u) noexcept
Definition unique_ptr.h:158
void reset(pointer p=nullptr) noexcept
Definition unique_ptr.h:203
unique_ptr(pointer p) noexcept
Definition unique_ptr.h:141
unique_ptr & operator=(fl::nullptr_t) noexcept
Definition unique_ptr.h:175
Deleter & get_deleter() noexcept
Definition unique_ptr.h:189
unique_ptr(unique_ptr< U, E > &&u) noexcept
Definition unique_ptr.h:150
unique_ptr(const unique_ptr &)=delete
pointer release() noexcept
Definition unique_ptr.h:197
unique_ptr & operator=(const unique_ptr &)=delete
unique_ptr & operator=(unique_ptr< U, E > &&u) noexcept
Definition unique_ptr.h:168
const Deleter & get_deleter() const noexcept
Definition unique_ptr.h:190
constexpr unique_ptr(fl::nullptr_t) noexcept
Definition unique_ptr.h:140
unique_ptr(pointer p, const Deleter &d) noexcept
Definition unique_ptr.h:142
constexpr unique_ptr() noexcept
Definition unique_ptr.h:139
pointer get() const noexcept
Definition unique_ptr.h:188
unique_ptr(pointer p, Deleter &&d) noexcept
Definition unique_ptr.h:143
unique_ptr(unique_ptr &&u) noexcept
Definition unique_ptr.h:52
unique_ptr(unique_ptr< U, E > &&u) noexcept
Definition unique_ptr.h:56
unique_ptr & operator=(fl::nullptr_t) noexcept
Definition unique_ptr.h:81
unique_ptr(const unique_ptr &)=delete
unique_ptr(pointer p, const Deleter &d) noexcept
Definition unique_ptr.h:48
unique_ptr & operator=(unique_ptr &&u) noexcept
Definition unique_ptr.h:64
void reset(pointer p=nullptr) noexcept
Definition unique_ptr.h:110
unique_ptr(pointer p, Deleter &&d) noexcept
Definition unique_ptr.h:49
pointer get() const noexcept
Definition unique_ptr.h:94
constexpr unique_ptr(fl::nullptr_t) noexcept
Definition unique_ptr.h:46
constexpr unique_ptr() noexcept
Definition unique_ptr.h:45
T & operator*() const
Definition unique_ptr.h:100
const Deleter & get_deleter() const noexcept
Definition unique_ptr.h:96
pointer operator->() const noexcept
Definition unique_ptr.h:101
unique_ptr & operator=(const unique_ptr &)=delete
unique_ptr & operator=(unique_ptr< U, E > &&u) noexcept
Definition unique_ptr.h:74
unique_ptr(pointer p) noexcept
Definition unique_ptr.h:47
pointer release() noexcept
Definition unique_ptr.h:104
Deleter & get_deleter() noexcept
Definition unique_ptr.h:95
void swap(unique_ptr &u) noexcept
Definition unique_ptr.h:118
Implements the FastLED namespace macros.
constexpr remove_reference< T >::type && move(T &&t) noexcept
Definition move.h:27
void swap(array< T, N > &lhs, array< T, N > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Definition array.h:156
bool operator!=(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:151
decltype(nullptr) nullptr_t
Definition cstddef.h:11
__SIZE_TYPE__ size_t
Definition cstddef.h:17
bool operator==(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:141
IMPORTANT!
Definition crgb.h:20
void operator()(T *ptr) const
Definition unique_ptr.h:27
default_delete(const default_delete< U > &) noexcept
Definition unique_ptr.h:20
void operator()(T *ptr) const
Definition unique_ptr.h:14
default_delete()=default