FastLED 3.9.15
Loading...
Searching...
No Matches
weak_ptr.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/stl/shared_ptr.h"
5#include "fl/stl/noexcept.h"
6
7namespace fl {
8
9// std::weak_ptr compatible implementation
10template<typename T>
11class weak_ptr {
12private:
13 T* mPtr;
15
16public:
17 using element_type = T;
18
19 // Default constructor
20 weak_ptr() FL_NOEXCEPT : mPtr(nullptr), mControlBlock(nullptr) {}
21
22 // Copy constructor
23 weak_ptr(const weak_ptr& other) FL_NOEXCEPT : mPtr(other.mPtr), mControlBlock(other.mControlBlock) {
24 if (mControlBlock) {
25 ++mControlBlock->weak_count;
26 }
27 }
28
29 // Converting copy constructor
30 template<typename Y>
31 weak_ptr(const weak_ptr<Y>& other) FL_NOEXCEPT : mPtr(other.mPtr), mControlBlock(other.mControlBlock) {
32 if (mControlBlock) {
33 ++mControlBlock->weak_count;
34 }
35 }
36
37 // Constructor from shared_ptr
38 template<typename Y>
39 weak_ptr(const shared_ptr<Y>& shared) FL_NOEXCEPT : mPtr(shared.mPtr), mControlBlock(shared.mControlBlock) {
40 if (mControlBlock) {
41 ++mControlBlock->weak_count;
42 }
43 }
44
45 // Move constructor
46 weak_ptr(weak_ptr&& other) FL_NOEXCEPT : mPtr(other.mPtr), mControlBlock(other.mControlBlock) {
47 other.mPtr = nullptr;
48 other.mControlBlock = nullptr;
49 }
50
51 // Converting move constructor
52 template<typename Y>
53 weak_ptr(weak_ptr<Y>&& other) FL_NOEXCEPT : mPtr(other.mPtr), mControlBlock(other.mControlBlock) {
54 other.mPtr = nullptr;
55 other.mControlBlock = nullptr;
56 }
57
58 // Destructor
62
63 // Assignment operators
65 if (this != &other) {
66 release();
67 mPtr = other.mPtr;
68 mControlBlock = other.mControlBlock;
69 if (mControlBlock) {
70 ++mControlBlock->weak_count;
71 }
72 }
73 return *this;
74 }
75
76 template<typename Y>
78 release();
79 mPtr = other.mPtr;
80 mControlBlock = other.mControlBlock;
81 if (mControlBlock) {
82 ++mControlBlock->weak_count;
83 }
84 return *this;
85 }
86
87 template<typename Y>
89 release();
90 mPtr = shared.mPtr;
91 mControlBlock = shared.mControlBlock;
92 if (mControlBlock) {
93 ++mControlBlock->weak_count;
94 }
95 return *this;
96 }
97
99 if (this != &other) {
100 release();
101 mPtr = other.mPtr;
102 mControlBlock = other.mControlBlock;
103 other.mPtr = nullptr;
104 other.mControlBlock = nullptr;
105 }
106 return *this;
107 }
108
109 template<typename Y>
111 release();
112 mPtr = other.mPtr;
113 mControlBlock = other.mControlBlock;
114 other.mPtr = nullptr;
115 other.mControlBlock = nullptr;
116 return *this;
117 }
118
119 // Modifiers
121 release();
122 mPtr = nullptr;
123 mControlBlock = nullptr;
124 }
125
126 void swap(weak_ptr& other) FL_NOEXCEPT {
127 fl::swap(mPtr, other.mPtr);
128 fl::swap(mControlBlock, other.mControlBlock);
129 }
130
131 // Observers
132 long use_count() const FL_NOEXCEPT {
133 return mControlBlock ? static_cast<long>(mControlBlock->shared_count) : 0;
134 }
135
136 bool expired() const FL_NOEXCEPT {
137 return use_count() == 0;
138 }
139
141 if (expired()) {
142 return shared_ptr<T>();
143 }
144
145 // Try to acquire the shared pointer atomically
146 if (mControlBlock && mControlBlock->shared_count > 0) {
147 ++mControlBlock->shared_count;
149 }
150 return shared_ptr<T>();
151 }
152
153 // Ownership (similar to shared_ptr interface)
154 template<typename Y>
155 bool owner_before(const weak_ptr<Y>& other) const FL_NOEXCEPT {
156 return mControlBlock < other.mControlBlock;
157 }
158
159 template<typename Y>
160 bool owner_before(const shared_ptr<Y>& other) const FL_NOEXCEPT {
161 return mControlBlock < other.mControlBlock;
162 }
163
164 // Comparison operators (for compatibility with VectorSet)
165 bool operator==(const weak_ptr& other) const FL_NOEXCEPT {
166 return mPtr == other.mPtr && mControlBlock == other.mControlBlock;
167 }
168
169 bool operator!=(const weak_ptr& other) const FL_NOEXCEPT {
170 return !(*this == other);
171 }
172
173 template<typename Y>
174 bool operator==(const weak_ptr<Y>& other) const FL_NOEXCEPT {
175 return mPtr == other.mPtr && mControlBlock == other.mControlBlock;
176 }
177
178 template<typename Y>
179 bool operator!=(const weak_ptr<Y>& other) const FL_NOEXCEPT {
180 return !(*this == other);
181 }
182
183private:
185 if (mControlBlock) {
186 if (--mControlBlock->weak_count == 0 && mControlBlock->shared_count == 0) {
187 mControlBlock->destroy_control_block();
188 }
189 }
190 }
191
192 template<typename Y> friend class weak_ptr;
193 template<typename Y> friend class shared_ptr;
194};
195
196// Utility functions
197template<typename T>
199 lhs.swap(rhs);
200}
201
202} // namespace fl
203
204// Now we can complete the shared_ptr constructor that depends on weak_ptr
205namespace fl {
206
207template<typename T>
208template<typename Y>
209shared_ptr<T>::shared_ptr(const weak_ptr<Y>& weak) : mPtr(nullptr), mControlBlock(nullptr) {
210 if (!weak.expired()) {
211 if (weak.mControlBlock && weak.mControlBlock->shared_count > 0) {
212 ++weak.mControlBlock->shared_count;
213 mPtr = weak.mPtr;
214 mControlBlock = weak.mControlBlock;
215 }
216 }
217 if (!mPtr) {
218 // If construction failed (object was destroyed), throw bad_weak_ptr equivalent
219 // For now, just leave as default-constructed (nullptr)
220 }
221}
222
223} // namespace fl
detail::ControlBlockBase * mControlBlock
Definition shared_ptr.h:158
friend class weak_ptr
Definition shared_ptr.h:392
friend class shared_ptr
Definition shared_ptr.h:391
weak_ptr(const shared_ptr< Y > &shared) FL_NOEXCEPT
Definition weak_ptr.h:39
bool operator!=(const weak_ptr &other) const FL_NOEXCEPT
Definition weak_ptr.h:169
weak_ptr & operator=(weak_ptr &&other) FL_NOEXCEPT
Definition weak_ptr.h:98
void swap(weak_ptr &other) FL_NOEXCEPT
Definition weak_ptr.h:126
friend class weak_ptr
Definition weak_ptr.h:192
weak_ptr & operator=(const weak_ptr< Y > &other) FL_NOEXCEPT
Definition weak_ptr.h:77
weak_ptr(weak_ptr< Y > &&other) FL_NOEXCEPT
Definition weak_ptr.h:53
void reset() FL_NOEXCEPT
Definition weak_ptr.h:120
weak_ptr & operator=(const weak_ptr &other) FL_NOEXCEPT
Definition weak_ptr.h:64
bool operator==(const weak_ptr &other) const FL_NOEXCEPT
Definition weak_ptr.h:165
shared_ptr< T > lock() const FL_NOEXCEPT
Definition weak_ptr.h:140
bool operator==(const weak_ptr< Y > &other) const FL_NOEXCEPT
Definition weak_ptr.h:174
detail::ControlBlockBase * mControlBlock
Definition weak_ptr.h:14
weak_ptr(const weak_ptr< Y > &other) FL_NOEXCEPT
Definition weak_ptr.h:31
bool expired() const FL_NOEXCEPT
Definition weak_ptr.h:136
bool owner_before(const weak_ptr< Y > &other) const FL_NOEXCEPT
Definition weak_ptr.h:155
bool owner_before(const shared_ptr< Y > &other) const FL_NOEXCEPT
Definition weak_ptr.h:160
friend class shared_ptr
Definition weak_ptr.h:193
bool operator!=(const weak_ptr< Y > &other) const FL_NOEXCEPT
Definition weak_ptr.h:179
weak_ptr() FL_NOEXCEPT
Definition weak_ptr.h:20
weak_ptr & operator=(weak_ptr< Y > &&other) FL_NOEXCEPT
Definition weak_ptr.h:110
void release() FL_NOEXCEPT
Definition weak_ptr.h:184
long use_count() const FL_NOEXCEPT
Definition weak_ptr.h:132
weak_ptr(const weak_ptr &other) FL_NOEXCEPT
Definition weak_ptr.h:23
weak_ptr & operator=(const shared_ptr< Y > &shared) FL_NOEXCEPT
Definition weak_ptr.h:88
weak_ptr(weak_ptr &&other) FL_NOEXCEPT
Definition weak_ptr.h:46
~weak_ptr() FL_NOEXCEPT
Definition weak_ptr.h:59
void swap(T &a, T &b) FL_NOEXCEPT
Definition s16x16x4.h:877
void swap(array< T, N > &lhs, array< T, N > &rhs) FL_NOEXCEPT
Definition array.h:209
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT