FastLED 3.9.15
Loading...
Searching...
No Matches
unique_ptr.h
Go to the documentation of this file.
1#pragma once
2
4#include "fl/stl/utility.h" // for fl::move, fl::forward, fl::swap // IWYU pragma: keep
5#include "fl/stl/stdint.h" // for fl::size_t // IWYU pragma: keep
6#include "fl/stl/cstddef.h" // for fl::nullptr_t
7#include "fl/stl/noexcept.h"
9
10namespace fl {
11
12template<typename T>
14 void operator()(T* ptr) const FL_NOEXCEPT {
15 FL_STATIC_ASSERT(sizeof(T) > 0,
16 "Cannot delete pointer to incomplete type. "
17 "Ensure the type is fully defined where unique_ptr destructor is instantiated.");
18 delete ptr;
19 }
20
21 // Allow conversion from derived to base type deleters
22 template<typename U>
24
26};
27
28template<typename T>
29struct default_delete<T[]> {
30 void operator()(T* ptr) const FL_NOEXCEPT {
31 delete[] ptr;
32 }
33};
34
35template<typename T, typename Deleter = default_delete<T>>
37public:
38 using element_type = T;
39 using deleter_type = Deleter;
40 using pointer = T*;
41
42private:
44 Deleter mDeleter;
45
46public:
47 // Constructors
48 constexpr unique_ptr() FL_NOEXCEPT : mPtr(nullptr), mDeleter() {}
49 constexpr unique_ptr(fl::nullptr_t) FL_NOEXCEPT : mPtr(nullptr), mDeleter() {}
51 unique_ptr(pointer p, const Deleter& d) FL_NOEXCEPT : mPtr(p), mDeleter(d) {}
52 unique_ptr(pointer p, Deleter&& d) FL_NOEXCEPT : mPtr(p), mDeleter(fl::move(d)) {}
53
54 // Move constructor
55 unique_ptr(unique_ptr&& u) FL_NOEXCEPT : mPtr(u.release()), mDeleter(fl::move(u.mDeleter)) {}
56
57 // Converting move constructor
58 template<typename U, typename E>
60 : mPtr(u.release()), mDeleter(fl::move(u.get_deleter())) {}
61
62 // Copy semantics deleted
65
66 // Move assignment
68 if (this != &u) {
69 reset(u.release());
70 mDeleter = fl::move(u.mDeleter);
71 }
72 return *this;
73 }
74
75 // Converting move assignment
76 template<typename U, typename E>
78 reset(u.release());
79 mDeleter = fl::move(u.get_deleter());
80 return *this;
81 }
82
83 // nullptr assignment
85 reset();
86 return *this;
87 }
88
89 // Destructor
91 if (mPtr) {
93 }
94 }
95
96 // Observers
97 pointer get() const FL_NOEXCEPT { return mPtr; }
98 Deleter& get_deleter() FL_NOEXCEPT { return mDeleter; }
99 const Deleter& get_deleter() const FL_NOEXCEPT { return mDeleter; }
100 explicit operator bool() const FL_NOEXCEPT { return mPtr != nullptr; }
101
102 // Access
103 T& operator*() const FL_NOEXCEPT { return *mPtr; }
104 pointer operator->() const FL_NOEXCEPT { return mPtr; }
105
106 // Modifiers
108 pointer tmp = mPtr;
109 mPtr = nullptr;
110 return tmp;
111 }
112
113 void reset(pointer p = nullptr) FL_NOEXCEPT {
114 pointer old_ptr = mPtr;
115 mPtr = p;
116 if (old_ptr) {
117 mDeleter(old_ptr);
118 }
119 }
120
122 using fl::swap;
123 swap(mPtr, u.mPtr);
124 swap(mDeleter, u.mDeleter);
125 }
126};
127
128// Array specialization for scoped_array consolidation
129template<typename T, typename Deleter>
130class unique_ptr<T[], Deleter> {
131public:
132 using element_type = T;
133 using deleter_type = Deleter;
134 using pointer = T*;
135
136private:
138 Deleter mDeleter;
139
140public:
141 // Constructors
142 constexpr unique_ptr() FL_NOEXCEPT : mPtr(nullptr), mDeleter() {}
145 unique_ptr(pointer p, const Deleter& d) FL_NOEXCEPT : mPtr(p), mDeleter(d) {}
146 unique_ptr(pointer p, Deleter&& d) FL_NOEXCEPT : mPtr(p), mDeleter(fl::move(d)) {}
147
148 // Move constructor
149 unique_ptr(unique_ptr&& u) FL_NOEXCEPT : mPtr(u.release()), mDeleter(fl::move(u.mDeleter)) {}
150
151 // Converting move constructor
152 template<typename U, typename E>
154 : mPtr(u.release()), mDeleter(fl::move(u.get_deleter())) {}
155
156 // Copy semantics deleted
159
160 // Move assignment
162 if (this != &u) {
163 reset(u.release());
164 mDeleter = fl::move(u.mDeleter);
165 }
166 return *this;
167 }
168
169 // Converting move assignment
170 template<typename U, typename E>
172 reset(u.release());
173 mDeleter = fl::move(u.get_deleter());
174 return *this;
175 }
176
177 // nullptr assignment
179 reset();
180 return *this;
181 }
182
183 // Destructor
185 if (mPtr) {
186 mDeleter(mPtr);
187 }
188 }
189
190 // Observers
191 pointer get() const FL_NOEXCEPT { return mPtr; }
192 Deleter& get_deleter() FL_NOEXCEPT { return mDeleter; }
193 const Deleter& get_deleter() const FL_NOEXCEPT { return mDeleter; }
194 explicit operator bool() const FL_NOEXCEPT { return mPtr != nullptr; }
195
196 // Array access (replaces scoped_array functionality)
197 T& operator[](fl::size_t i) const FL_NOEXCEPT { return mPtr[i]; }
198
199 // Modifiers
201 pointer tmp = mPtr;
202 mPtr = nullptr;
203 return tmp;
204 }
205
206 void reset(pointer p = nullptr) FL_NOEXCEPT {
207 pointer old_ptr = mPtr;
208 mPtr = p;
209 if (old_ptr) {
210 mDeleter(old_ptr);
211 }
212 }
213
215 using fl::swap;
216 swap(mPtr, u.mPtr);
217 swap(mDeleter, u.mDeleter);
218 }
219};
220
221// Non-member functions using FL equivalents
222template<typename T, typename Deleter>
224 lhs.swap(rhs);
225}
226
227// Comparison operators using FL equivalents
228template<typename T1, typename Deleter1, typename T2, typename Deleter2>
230 return lhs.get() == rhs.get();
231}
232
233template<typename T1, typename Deleter1, typename T2, typename Deleter2>
235 return !(lhs == rhs);
236}
237
238template<typename T, typename Deleter>
240 return !ptr;
241}
242
243template<typename T, typename Deleter>
245 return !ptr;
246}
247
248template<typename T, typename Deleter>
250 return static_cast<bool>(ptr);
251}
252
253template<typename T, typename Deleter>
255 return static_cast<bool>(ptr);
256}
257
258// make_unique function for consistency with std::make_unique
259template<typename T, typename... Args>
260typename fl::enable_if<!fl::is_array<T>::value, unique_ptr<T>>::type
262 return unique_ptr<T>(new T(fl::forward<Args>(args)...));
263}
264
265// make_unique for arrays
266template<typename T>
267typename fl::enable_if<fl::is_array<T>::value, unique_ptr<T>>::type
269 typedef typename fl::remove_extent<T>::type U;
270 return unique_ptr<T>(new U[size]());
271}
272
273} // namespace fl
unique_ptr(unique_ptr< U, E > &&u) FL_NOEXCEPT
Definition unique_ptr.h:153
unique_ptr & operator=(fl::nullptr_t) FL_NOEXCEPT
Definition unique_ptr.h:178
constexpr unique_ptr(fl::nullptr_t) FL_NOEXCEPT
Definition unique_ptr.h:143
unique_ptr(const unique_ptr &) FL_NOEXCEPT=delete
unique_ptr(pointer p, const Deleter &d) FL_NOEXCEPT
Definition unique_ptr.h:145
constexpr unique_ptr() FL_NOEXCEPT
Definition unique_ptr.h:142
void reset(pointer p=nullptr) FL_NOEXCEPT
Definition unique_ptr.h:206
unique_ptr(pointer p, Deleter &&d) FL_NOEXCEPT
Definition unique_ptr.h:146
unique_ptr & operator=(unique_ptr< U, E > &&u) FL_NOEXCEPT
Definition unique_ptr.h:171
T & operator[](fl::size_t i) const FL_NOEXCEPT
Definition unique_ptr.h:197
unique_ptr & operator=(unique_ptr &&u) FL_NOEXCEPT
Definition unique_ptr.h:161
unique_ptr(pointer p) FL_NOEXCEPT
Definition unique_ptr.h:144
Deleter & get_deleter() FL_NOEXCEPT
Definition unique_ptr.h:192
pointer release() FL_NOEXCEPT
Definition unique_ptr.h:200
void swap(unique_ptr &u) FL_NOEXCEPT
Definition unique_ptr.h:214
pointer get() const FL_NOEXCEPT
Definition unique_ptr.h:191
const Deleter & get_deleter() const FL_NOEXCEPT
Definition unique_ptr.h:193
unique_ptr & operator=(const unique_ptr &) FL_NOEXCEPT=delete
unique_ptr(unique_ptr &&u) FL_NOEXCEPT
Definition unique_ptr.h:149
constexpr unique_ptr(fl::nullptr_t) FL_NOEXCEPT
Definition unique_ptr.h:49
unique_ptr(pointer p, Deleter &&d) FL_NOEXCEPT
Definition unique_ptr.h:52
unique_ptr & operator=(unique_ptr &&u) FL_NOEXCEPT
Definition unique_ptr.h:67
pointer operator->() const FL_NOEXCEPT
Definition unique_ptr.h:104
unique_ptr(unique_ptr &&u) FL_NOEXCEPT
Definition unique_ptr.h:55
unique_ptr(pointer p, const Deleter &d) FL_NOEXCEPT
Definition unique_ptr.h:51
Deleter & get_deleter() FL_NOEXCEPT
Definition unique_ptr.h:98
pointer release() FL_NOEXCEPT
Definition unique_ptr.h:107
~unique_ptr() FL_NOEXCEPT
Definition unique_ptr.h:90
pointer get() const FL_NOEXCEPT
Definition unique_ptr.h:97
unique_ptr(pointer p) FL_NOEXCEPT
Definition unique_ptr.h:50
unique_ptr & operator=(const unique_ptr &) FL_NOEXCEPT=delete
const Deleter & get_deleter() const FL_NOEXCEPT
Definition unique_ptr.h:99
unique_ptr & operator=(unique_ptr< U, E > &&u) FL_NOEXCEPT
Definition unique_ptr.h:77
T & operator*() const FL_NOEXCEPT
Definition unique_ptr.h:103
void reset(pointer p=nullptr) FL_NOEXCEPT
Definition unique_ptr.h:113
void swap(unique_ptr &u) FL_NOEXCEPT
Definition unique_ptr.h:121
unique_ptr(unique_ptr< U, E > &&u) FL_NOEXCEPT
Definition unique_ptr.h:59
constexpr unique_ptr() FL_NOEXCEPT
Definition unique_ptr.h:48
unique_ptr(const unique_ptr &) FL_NOEXCEPT=delete
unique_ptr & operator=(fl::nullptr_t) FL_NOEXCEPT
Definition unique_ptr.h:84
constexpr T && forward(typename remove_reference< T >::type &t) FL_NOEXCEPT
Definition s16x16x4.h:234
decltype(nullptr) nullptr_t
Definition s16x16x4.h:13
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
Definition s16x16x4.h:28
void swap(T &a, T &b) FL_NOEXCEPT
Definition s16x16x4.h:877
__SIZE_TYPE__ size_t
Definition s16x16x4.h:16
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
Definition move.h:28
fl::enable_if<!fl::is_array< T >::value, unique_ptr< T > >::type make_unique(Args &&... args) FL_NOEXCEPT
Definition unique_ptr.h:261
FASTLED_FORCE_INLINE bool operator!=(const CRGB &lhs, const CRGB &rhs) FL_NOEXCEPT
Check if two CRGB objects do not have the same color data.
Definition crgb.h:739
void swap(array< T, N > &lhs, array< T, N > &rhs) FL_NOEXCEPT
Definition array.h:209
FASTLED_FORCE_INLINE bool operator==(const CRGB &lhs, const CRGB &rhs) FL_NOEXCEPT
Check if two CRGB objects have the same color data.
Definition crgb.h:733
Base definition for an LED controller.
Definition crgb.hpp:179
corkscrew_args args
Definition old.h:149
#define FL_STATIC_ASSERT(...)
#define FL_NOEXCEPT
Portable compile-time assertion wrapper.
void operator()(T *ptr) const FL_NOEXCEPT
Definition unique_ptr.h:30
default_delete(const default_delete< U > &) FL_NOEXCEPT
Definition unique_ptr.h:23
default_delete() FL_NOEXCEPT=default
void operator()(T *ptr) const FL_NOEXCEPT
Definition unique_ptr.h:14