FastLED 3.10.6
Loading...
Searching...
No Matches
optional.h
Go to the documentation of this file.
1
2
3#pragma once
4
5#include "fl/stl/variant.h"
7#include "fl/stl/noexcept.h"
8
9namespace fl {
10
11// nullopt support for compatibility with std::optional patterns
12struct nullopt_t {};
13constexpr nullopt_t nullopt{};
14
15template <typename T> class Optional;
16template <typename T> using optional = Optional<T>;
17
18struct Empty {};
19
20template <typename T> class Optional {
21
22 public:
25 Optional(const Optional &other) FL_NO_EXCEPT : mValue(other.mValue) {}
26 Optional(Optional &&other) FL_NO_EXCEPT : mValue(fl::move(other.mValue)) {}
27
31
34
36 template <typename... Args>
37 void emplace(Args&&... args) FL_NO_EXCEPT {
39 }
40
41 bool empty() const FL_NO_EXCEPT { return !mValue.template is<T>(); }
42 bool has_value() const FL_NO_EXCEPT { return !empty(); } // std::optional compatibility
43 T *ptr() FL_NO_EXCEPT { return mValue.template ptr<T>(); }
44 const T *ptr() const FL_NO_EXCEPT { return mValue.template ptr<T>(); }
45
46 void reset() FL_NO_EXCEPT { mValue.reset(); }
47
49 if (this != &other) {
50 mValue = other.mValue;
51 }
52 return *this;
53 }
54
56 if (this != &other) {
57 mValue = fl::move(other.mValue);
58 }
59 return *this;
60 }
61
63 mValue = Empty();
64 return *this;
65 }
66
68 mValue = value;
69 return *this;
70 }
71
74 return *this;
75 }
76
77 bool operator()() const FL_NO_EXCEPT { return !empty(); }
78 bool operator!() const FL_NO_EXCEPT { return empty(); }
79
80 // Explicit conversion to bool for contextual boolean evaluation
81 explicit operator bool() const FL_NO_EXCEPT { return !empty(); }
82
83 bool operator==(const Optional &other) const FL_NO_EXCEPT {
84 if (empty() && other.empty()) {
85 return true;
86 }
87 if (empty() || other.empty()) {
88 return false;
89 }
90 return *ptr() == *other.ptr();
91 }
92
93 bool operator!=(const Optional &other) const FL_NO_EXCEPT { return !(*this == other); }
94
95 bool operator==(const T &value) const FL_NO_EXCEPT {
96 if (empty()) {
97 return false;
98 }
99 return *ptr() == value;
100 }
101
102 bool operator==(nullopt_t) const FL_NO_EXCEPT { return empty(); }
103 bool operator!=(nullopt_t) const FL_NO_EXCEPT { return !empty(); }
104
105 // Dereference operators for compatibility with std::optional
106 T& operator*() FL_NO_EXCEPT { return *ptr(); }
107 const T& operator*() const FL_NO_EXCEPT { return *ptr(); }
108 T* operator->() FL_NO_EXCEPT { return ptr(); }
109 const T* operator->() const FL_NO_EXCEPT { return ptr(); }
110
111 // value() method for std::optional compatibility
112 T& value() FL_NO_EXCEPT { return *ptr(); }
113 const T& value() const FL_NO_EXCEPT { return *ptr(); }
114
115 // value_or() method for std::optional compatibility
116 // Returns the contained value if present, otherwise returns the provided default
117 T value_or(const T& default_value) const FL_NO_EXCEPT {
118 return has_value() ? *ptr() : default_value;
119 }
120
121 // value_or() overload for rvalue default values
122 T value_or(T&& default_value) const FL_NO_EXCEPT {
123 return has_value() ? *ptr() : fl::move(default_value);
124 }
125
126 template <typename TT, typename UU>
127 bool operator==(const variant<TT, UU> &other) const FL_NO_EXCEPT {
128 if (!other.template holdsTypeOf<T>()) {
129 return false;
130 }
131 if (empty()) {
132 return false;
133 }
134 if (other.empty()) {
135 return false;
136 }
137 return *ptr() == *other.template ptr<T>();
138 }
139
141 if (this != &other) {
142 mValue.swap(other.mValue);
143 }
144 }
145
146 private:
147 fl::variant<T, Empty> mValue;
148};
149
150// Specialization for rvalue references Optional<T&&>
151// This allows optionals to hold and forward rvalue references properly
152template <typename T> class Optional<T&&> {
153 public:
154 Optional() FL_NO_EXCEPT : mPtr(nullptr) {}
156
157 // Construct from rvalue reference
159
160 // Copy constructor deleted - rvalue references cannot be copied
162
163 // Move constructor - transfers the reference
164 Optional(Optional&& other) FL_NO_EXCEPT : mPtr(other.mPtr) {
165 other.mPtr = nullptr;
166 }
167
169
170 bool empty() const FL_NO_EXCEPT { return mPtr == nullptr; }
171 bool has_value() const FL_NO_EXCEPT { return !empty(); }
172 T* ptr() FL_NO_EXCEPT { return mPtr; }
173 const T* ptr() const FL_NO_EXCEPT { return mPtr; }
174
175 void reset() FL_NO_EXCEPT { mPtr = nullptr; }
176
177 // Copy assignment deleted - rvalue references cannot be copied
179
180 // Move assignment
182 if (this != &other) {
183 mPtr = other.mPtr;
184 other.mPtr = nullptr;
185 }
186 return *this;
187 }
188
190 reset();
191 return *this;
192 }
193
194 bool operator()() const FL_NO_EXCEPT { return !empty(); }
195 bool operator!() const FL_NO_EXCEPT { return empty(); }
196
197 // Explicit conversion to bool
198 explicit operator bool() const FL_NO_EXCEPT { return !empty(); }
199
200 bool operator==(const Optional& other) const FL_NO_EXCEPT {
201 if (empty() && other.empty()) {
202 return true;
203 }
204 if (empty() || other.empty()) {
205 return false;
206 }
207 return *mPtr == *other.mPtr;
208 }
209
210 bool operator!=(const Optional& other) const FL_NO_EXCEPT { return !(*this == other); }
211
212 bool operator==(nullopt_t) const FL_NO_EXCEPT { return empty(); }
213 bool operator!=(nullopt_t) const FL_NO_EXCEPT { return !empty(); }
214
215 // Dereference operators - returns rvalue reference to forward the value
217 const T& operator*() const FL_NO_EXCEPT { return *mPtr; }
219 const T& get() const FL_NO_EXCEPT { return *mPtr; }
220
221 // Arrow operator - returns pointer for member access
222 T* operator->() FL_NO_EXCEPT { return mPtr; }
223 const T* operator->() const FL_NO_EXCEPT { return mPtr; }
224
225 // value() method for std::optional compatibility
227 const T& value() const FL_NO_EXCEPT { return *mPtr; }
228
229 private:
230 T* mPtr; // Pointer to the rvalue reference (only valid during the lifetime of the temporary)
231};
232
233// Helper function to create optionals
234template <typename T>
238
239template <typename T>
243
244} // namespace fl
Optional(const Optional &) FL_NO_EXCEPT=delete
Optional() FL_NO_EXCEPT
Definition optional.h:154
const T * operator->() const FL_NO_EXCEPT
Definition optional.h:223
const T & value() const FL_NO_EXCEPT
Definition optional.h:227
bool operator()() const FL_NO_EXCEPT
Definition optional.h:194
void reset() FL_NO_EXCEPT
Definition optional.h:175
Optional & operator=(nullopt_t) FL_NO_EXCEPT
Definition optional.h:189
const T & get() const FL_NO_EXCEPT
Definition optional.h:219
Optional & operator=(Optional &&other) FL_NO_EXCEPT
Definition optional.h:181
bool empty() const FL_NO_EXCEPT
Definition optional.h:170
Optional(Optional &&other) FL_NO_EXCEPT
Definition optional.h:164
bool operator!() const FL_NO_EXCEPT
Definition optional.h:195
T * ptr() FL_NO_EXCEPT
Definition optional.h:172
T * operator->() FL_NO_EXCEPT
Definition optional.h:222
bool operator!=(const Optional &other) const FL_NO_EXCEPT
Definition optional.h:210
bool operator==(const Optional &other) const FL_NO_EXCEPT
Definition optional.h:200
bool operator==(nullopt_t) const FL_NO_EXCEPT
Definition optional.h:212
T && value() FL_NO_EXCEPT
Definition optional.h:226
const T * ptr() const FL_NO_EXCEPT
Definition optional.h:173
Optional(nullopt_t) FL_NO_EXCEPT
Definition optional.h:155
T && operator*() FL_NO_EXCEPT
Definition optional.h:216
~Optional() FL_NO_EXCEPT
Definition optional.h:168
Optional(T &&value) FL_NO_EXCEPT
Definition optional.h:158
T && get() FL_NO_EXCEPT
Definition optional.h:218
const T & operator*() const FL_NO_EXCEPT
Definition optional.h:217
bool operator!=(nullopt_t) const FL_NO_EXCEPT
Definition optional.h:213
bool has_value() const FL_NO_EXCEPT
Definition optional.h:171
Optional & operator=(const Optional &) FL_NO_EXCEPT=delete
Optional(const Optional &other) FL_NO_EXCEPT
Definition optional.h:25
T value_or(T &&default_value) const FL_NO_EXCEPT
Definition optional.h:122
const T * operator->() const FL_NO_EXCEPT
Definition optional.h:109
bool operator==(const Optional &other) const FL_NO_EXCEPT
Definition optional.h:83
void reset() FL_NO_EXCEPT
Definition optional.h:46
bool operator()() const FL_NO_EXCEPT
Definition optional.h:77
Optional & operator=(nullopt_t) FL_NO_EXCEPT
Definition optional.h:62
T * operator->() FL_NO_EXCEPT
Definition optional.h:108
bool operator==(nullopt_t) const FL_NO_EXCEPT
Definition optional.h:102
T & operator*() FL_NO_EXCEPT
Definition optional.h:106
Optional() FL_NO_EXCEPT
Definition optional.h:23
const T & value() const FL_NO_EXCEPT
Definition optional.h:113
bool operator!() const FL_NO_EXCEPT
Definition optional.h:78
T value_or(const T &default_value) const FL_NO_EXCEPT
Definition optional.h:117
Optional & operator=(T &&value) FL_NO_EXCEPT
Definition optional.h:72
T * ptr() FL_NO_EXCEPT
Definition optional.h:43
bool empty() const FL_NO_EXCEPT
Definition optional.h:41
void emplace(Args &&... args) FL_NO_EXCEPT
Construct value in-place with variadic arguments.
Definition optional.h:37
bool operator!=(nullopt_t) const FL_NO_EXCEPT
Definition optional.h:103
Optional(const T &value) FL_NO_EXCEPT
Definition optional.h:28
Optional & operator=(const Optional &other) FL_NO_EXCEPT
Definition optional.h:48
void swap(Optional &other) FL_NO_EXCEPT
Definition optional.h:140
bool operator==(const T &value) const FL_NO_EXCEPT
Definition optional.h:95
Optional(nullopt_t) FL_NO_EXCEPT
Definition optional.h:24
fl::variant< T, Empty > mValue
Definition optional.h:147
T & value() FL_NO_EXCEPT
Definition optional.h:112
bool has_value() const FL_NO_EXCEPT
Definition optional.h:42
const T * ptr() const FL_NO_EXCEPT
Definition optional.h:44
Optional(T &&value) FL_NO_EXCEPT
Definition optional.h:29
bool operator!=(const Optional &other) const FL_NO_EXCEPT
Definition optional.h:93
const T & operator*() const FL_NO_EXCEPT
Definition optional.h:107
void emplace(T &&value) FL_NO_EXCEPT
Emplace with rvalue reference.
Definition optional.h:33
Optional & operator=(Optional &&other) FL_NO_EXCEPT
Definition optional.h:55
Optional & operator=(const T &value) FL_NO_EXCEPT
Definition optional.h:67
~Optional() FL_NO_EXCEPT
Definition optional.h:30
bool operator==(const variant< TT, UU > &other) const FL_NO_EXCEPT
Definition optional.h:127
Optional(Optional &&other) FL_NO_EXCEPT
Definition optional.h:26
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
Definition move.h:28
constexpr int type_rank< T >::value
Optional< T > optional
Definition optional.h:16
optional< T > make_optional(const T &value) FL_NO_EXCEPT
Definition optional.h:235
constexpr T && forward(typename remove_reference< T >::type &t) FL_NO_EXCEPT
InputGamut g FL_NO_EXCEPT
Definition rgbw.h:121
constexpr nullopt_t nullopt
Definition optional.h:13
Base definition for an LED controller.
Definition crgb.hpp:179
corkscrew_args args
Definition old.h:149