FastLED 3.9.15
Loading...
Searching...
No Matches
scoped_ptr.h
Go to the documentation of this file.
1
2#pragma once
3
4#include <stddef.h>
5#include <stdint.h>
6
7#include "fl/allocator.h"
8#include "fl/inplacenew.h"
9#include "fl/namespace.h"
10// #include "fl/warn.h"
11#include "fl/deprecated.h"
12
13namespace fl {
14
15template <typename T> struct ArrayDeleter {
16 ArrayDeleter() = default;
17 void operator()(T *ptr) { delete[] ptr; }
18};
19
20template <typename T> struct PointerDeleter {
21 void operator()(T *ptr) { delete ptr; }
22};
23
24template <typename T, typename Deleter = PointerDeleter<T>> class scoped_ptr {
25 public:
26 // Constructor
27 explicit scoped_ptr(T *ptr = nullptr, Deleter deleter = Deleter())
28 : ptr_(ptr), deleter_(deleter) {}
29
30 // Destructor
32
33 // Disable copy semantics (no copying allowed)
34 scoped_ptr(const scoped_ptr &) = delete;
35 scoped_ptr &operator=(const scoped_ptr &) = delete;
36
37 // Move constructor
38 scoped_ptr(scoped_ptr &&other) noexcept
39 : ptr_(other.ptr_), deleter_(other.deleter_) {
40 other.ptr_ = nullptr;
41 other.deleter_ = {};
42 }
43
44 // // Move assignment operator
45 // scoped_ptr &operator=(scoped_ptr &&other) noexcept {
46 // if (this != &other) {
47 // reset(other.ptr_);
48 // deleter_ = other.deleter_;
49 // other.ptr_ = nullptr;
50 // other.deleter_ = {};
51 // }
52 // return *this;
53 // }
54
55 // Access the managed object
56 T *operator->() const { return ptr_; }
57
58 // Dereference the managed object
59 T &operator*() const { return *ptr_; }
60
61 // Get the raw pointer
62 T *get() const { return ptr_; }
63
64 // Boolean conversion operator
65 explicit operator bool() const noexcept { return ptr_ != nullptr; }
66
67 // Logical NOT operator
68 bool operator!() const noexcept { return ptr_ == nullptr; }
69
70 // Release the managed object and reset the pointer
71 void reset(T *ptr = nullptr) {
72 if (ptr_ != ptr) {
74 ptr_ = ptr;
75 }
76 }
77
78 T *release() {
79 T *tmp = ptr_;
80 ptr_ = nullptr;
81 return tmp;
82 }
83
84 void swap(scoped_ptr &other) noexcept {
85 T *tmp = ptr_;
86 ptr_ = other.ptr_;
87 other.ptr_ = tmp;
88 }
89
90 private:
91 T *ptr_; // Managed pointer
92 Deleter deleter_; // Custom deleter
93};
94
95
96
97// A second variant, this one allows you to allocate seperataly and use
98// a deleter function to manage the deletion. Some older code needs this.
99
100template <typename T, typename Deleter = ArrayDeleter<T>> class scoped_array {
101 public:
102 FASTLED_DEPRECATED_CLASS("Use fl::vector<T, fl::allocator_psram<T>> instead");
103 // Constructor
104 explicit scoped_array(T *arr = nullptr) : arr_(arr) {}
105 scoped_array(T *arr, Deleter deleter) : arr_(arr), deleter_(deleter) {}
106
107 // Destructor
109
110 // Disable copy semantics (no copying allowed)
111 scoped_array(const scoped_array &) = delete;
113
114 // Move constructor
115 scoped_array(scoped_array &&other) noexcept
116 : arr_(other.arr_), deleter_(other.deleter_) {
117 other.arr_ = nullptr;
118 other.deleter_ = {};
119 }
120
121 // Move assignment operator
123 if (this != &other) {
124 reset(other.arr_);
125 other.arr_ = nullptr;
126 }
127 return *this;
128 }
129
130 // Array subscript operator
131 T &operator[](size_t i) const { return arr_[i]; }
132
133 // Get the raw pointer
134 T *get() const { return arr_; }
135
136 // Boolean conversion operator
137 explicit operator bool() const noexcept { return arr_ != nullptr; }
138
139 // Logical NOT operator
140 bool operator!() const noexcept { return arr_ == nullptr; }
141
142 // Release the managed array and reset the pointer
143 void reset(T *arr = nullptr) {
144 if (arr_ == arr) {
145 return;
146 }
147 deleter_(arr_);
148 arr_ = arr;
149 }
150
151 void clear() { reset(); }
152
153 T *release() {
154 T *tmp = arr_;
155 arr_ = nullptr;
156 return tmp;
157 }
158
159 void swap(scoped_array &other) noexcept {
160 T *tmp = arr_;
161 arr_ = other.arr_;
162 other.arr_ = tmp;
163 }
164
165 private:
166 T *arr_; // Managed array pointer
167 Deleter deleter_ = {};
168};
169
170
171
172// A variant of scoped_ptr where allocation is done completly via a fl::allocator.
173template <typename T, typename Alloc = fl::allocator<T>> class scoped_array2 {
174 public:
175 FASTLED_DEPRECATED_CLASS("Use fl::vector<T, fl::allocator_psram<T>> instead");
176 Alloc mAlloc; // Allocator instance to manage memory allocation
177 // Constructor
178 explicit scoped_array2(size_t size = 0)
179 : arr_(nullptr), size_(size) {
180 if (size > 0) {
181 arr_ = mAlloc.allocate(size);
182 // Default initialize each element
183 for (size_t i = 0; i < size; ++i) {
184 mAlloc.construct(&arr_[i]);
185 }
186 }
187 }
188
189 // Destructor
191 if (arr_) {
192 // Call destructor on each element
193 for (size_t i = 0; i < size_; ++i) {
194 mAlloc.destroy(&arr_[i]);
195 }
196 mAlloc.deallocate(arr_, size_);
197 }
198 }
199
200 // Disable copy semantics (no copying allowed)
201 scoped_array2(const scoped_array2 &) = delete;
203
204 // Move constructor
205 scoped_array2(scoped_array2 &&other) noexcept
206 : arr_(other.arr_), size_(other.size_) {
207 other.arr_ = nullptr;
208 other.size_ = 0;
209 }
210
211 // Move assignment operator
213 if (this != &other) {
214 reset();
215 arr_ = other.arr_;
216 size_ = other.size_;
217 other.arr_ = nullptr;
218 other.size_ = 0;
219 }
220 return *this;
221 }
222
223 // Array subscript operator
224 T &operator[](size_t i) const { return arr_[i]; }
225
226 // Get the raw pointer
227 T *get() const { return arr_; }
228
229 // Get the size of the array
230 size_t size() const { return size_; }
231
232 // Boolean conversion operator
233 explicit operator bool() const noexcept { return arr_ != nullptr; }
234
235 // Logical NOT operator
236 bool operator!() const noexcept { return arr_ == nullptr; }
237
238 // Release the managed array and reset the pointer
239 void reset(size_t new_size = 0) {
240 if (arr_) {
241 // Call destructor on each element
242 for (size_t i = 0; i < size_; ++i) {
243 // arr_[i].~T();
244 mAlloc.destroy(&arr_[i]);
245 }
246 // ::operator delete(arr_);
247 mAlloc.deallocate(arr_, size_);
248 arr_ = nullptr;
249 }
250
251 size_ = new_size;
252 if (new_size > 0) {
253 // arr_ = static_cast<T*>(::operator new(new_size * sizeof(T)));
254 arr_ = mAlloc.allocate(new_size);
255 // Default initialize each element
256 for (size_t i = 0; i < new_size; ++i) {
257 // new (&arr_[i]) T();
258 mAlloc.construct(&arr_[i]);
259 }
260 }
261 }
262
263 // Release ownership of the array
264 T *release() {
265 T *tmp = arr_;
266 arr_ = nullptr;
267 size_ = 0;
268 return tmp;
269 }
270
271 void swap(scoped_array2 &other) noexcept {
272 T *tmp_arr = arr_;
273 size_t tmp_size = size_;
274
275 arr_ = other.arr_;
276 size_ = other.size_;
277
278 other.arr_ = tmp_arr;
279 other.size_ = tmp_size;
280 }
281
282 private:
283 T *arr_ = nullptr; // Managed array pointer
284 size_t size_ = 0; // Size of the array
285};
286
287
288
289} // namespace fl
bool operator!() const noexcept
Definition scoped_ptr.h:236
scoped_array2(const scoped_array2 &)=delete
scoped_array2(size_t size=0)
Definition scoped_ptr.h:178
scoped_array2 & operator=(const scoped_array2 &)=delete
FASTLED_DEPRECATED_CLASS("Use fl::vector<T, fl::allocator_psram<T>> instead")
void swap(scoped_array2 &other) noexcept
Definition scoped_ptr.h:271
void reset(size_t new_size=0)
Definition scoped_ptr.h:239
size_t size() const
Definition scoped_ptr.h:230
scoped_array2(scoped_array2 &&other) noexcept
Definition scoped_ptr.h:205
T * get() const
Definition scoped_ptr.h:227
scoped_array2 & operator=(scoped_array2 &&other) noexcept
Definition scoped_ptr.h:212
T & operator[](size_t i) const
Definition scoped_ptr.h:224
void reset(T *arr=nullptr)
Definition scoped_ptr.h:143
scoped_array & operator=(const scoped_array &)=delete
scoped_array(scoped_array &&other) noexcept
Definition scoped_ptr.h:115
void swap(scoped_array &other) noexcept
Definition scoped_ptr.h:159
bool operator!() const noexcept
Definition scoped_ptr.h:140
T & operator[](size_t i) const
Definition scoped_ptr.h:131
T * get() const
Definition scoped_ptr.h:134
FASTLED_DEPRECATED_CLASS("Use fl::vector<T, fl::allocator_psram<T>> instead")
scoped_array(const scoped_array &)=delete
scoped_array(T *arr, Deleter deleter)
Definition scoped_ptr.h:105
scoped_array & operator=(scoped_array &&other) noexcept
Definition scoped_ptr.h:122
scoped_array(T *arr=nullptr)
Definition scoped_ptr.h:104
T & operator*() const
Definition scoped_ptr.h:59
void swap(scoped_ptr &other) noexcept
Definition scoped_ptr.h:84
bool operator!() const noexcept
Definition scoped_ptr.h:68
scoped_ptr(scoped_ptr &&other) noexcept
Definition scoped_ptr.h:38
T * operator->() const
Definition scoped_ptr.h:56
scoped_ptr(T *ptr=nullptr, Deleter deleter=Deleter())
Definition scoped_ptr.h:27
scoped_ptr & operator=(const scoped_ptr &)=delete
T * get() const
Definition scoped_ptr.h:62
void reset(T *ptr=nullptr)
Definition scoped_ptr.h:71
Deleter deleter_
Definition scoped_ptr.h:92
scoped_ptr(const scoped_ptr &)=delete
Implements the FastLED namespace macros.
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16
ArrayDeleter()=default
void operator()(T *ptr)
Definition scoped_ptr.h:17
void operator()(T *ptr)
Definition scoped_ptr.h:21