FastLED 3.9.15
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_NOEXCEPT : mValue(other.mValue) {}
26 Optional(Optional &&other) FL_NOEXCEPT : mValue(fl::move(other.mValue)) {}
27
31
34
36 template <typename... Args>
37 void emplace(Args&&... args) FL_NOEXCEPT {
39 }
40
41 bool empty() const FL_NOEXCEPT { return !mValue.template is<T>(); }
42 bool has_value() const FL_NOEXCEPT { return !empty(); } // std::optional compatibility
43 T *ptr() FL_NOEXCEPT { return mValue.template ptr<T>(); }
44 const T *ptr() const FL_NOEXCEPT { return mValue.template ptr<T>(); }
45
46 void reset() FL_NOEXCEPT { 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_NOEXCEPT { return !empty(); }
78 bool operator!() const FL_NOEXCEPT { return empty(); }
79
80 // Explicit conversion to bool for contextual boolean evaluation
81 explicit operator bool() const FL_NOEXCEPT { return !empty(); }
82
83 bool operator==(const Optional &other) const FL_NOEXCEPT {
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_NOEXCEPT { return !(*this == other); }
94
95 bool operator==(const T &value) const FL_NOEXCEPT {
96 if (empty()) {
97 return false;
98 }
99 return *ptr() == value;
100 }
101
102 bool operator==(nullopt_t) const FL_NOEXCEPT { return empty(); }
103 bool operator!=(nullopt_t) const FL_NOEXCEPT { return !empty(); }
104
105 // Dereference operators for compatibility with std::optional
106 T& operator*() FL_NOEXCEPT { return *ptr(); }
107 const T& operator*() const FL_NOEXCEPT { return *ptr(); }
108 T* operator->() FL_NOEXCEPT { return ptr(); }
109 const T* operator->() const FL_NOEXCEPT { return ptr(); }
110
111 // value() method for std::optional compatibility
112 T& value() FL_NOEXCEPT { return *ptr(); }
113 const T& value() const FL_NOEXCEPT { 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_NOEXCEPT {
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_NOEXCEPT {
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_NOEXCEPT {
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
140 void swap(Optional &other) FL_NOEXCEPT {
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_NOEXCEPT : mPtr(nullptr) {}
156
157 // Construct from rvalue reference
159
160 // Copy constructor deleted - rvalue references cannot be copied
161 Optional(const Optional&) FL_NOEXCEPT = delete;
162
163 // Move constructor - transfers the reference
164 Optional(Optional&& other) FL_NOEXCEPT : mPtr(other.mPtr) {
165 other.mPtr = nullptr;
166 }
167
169
170 bool empty() const FL_NOEXCEPT { return mPtr == nullptr; }
171 bool has_value() const FL_NOEXCEPT { return !empty(); }
172 T* ptr() FL_NOEXCEPT { return mPtr; }
173 const T* ptr() const FL_NOEXCEPT { return mPtr; }
174
175 void reset() FL_NOEXCEPT { 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_NOEXCEPT { return !empty(); }
195 bool operator!() const FL_NOEXCEPT { return empty(); }
196
197 // Explicit conversion to bool
198 explicit operator bool() const FL_NOEXCEPT { return !empty(); }
199
200 bool operator==(const Optional& other) const FL_NOEXCEPT {
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_NOEXCEPT { return !(*this == other); }
211
212 bool operator==(nullopt_t) const FL_NOEXCEPT { return empty(); }
213 bool operator!=(nullopt_t) const FL_NOEXCEPT { return !empty(); }
214
215 // Dereference operators - returns rvalue reference to forward the value
217 const T& operator*() const FL_NOEXCEPT { return *mPtr; }
218 T&& get() FL_NOEXCEPT { return fl::forward<T>(*mPtr); }
219 const T& get() const FL_NOEXCEPT { return *mPtr; }
220
221 // Arrow operator - returns pointer for member access
222 T* operator->() FL_NOEXCEPT { return mPtr; }
223 const T* operator->() const FL_NOEXCEPT { return mPtr; }
224
225 // value() method for std::optional compatibility
227 const T& value() const FL_NOEXCEPT { 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
const T * ptr() const FL_NOEXCEPT
Definition optional.h:173
T * operator->() FL_NOEXCEPT
Definition optional.h:222
Optional(T &&value) FL_NOEXCEPT
Definition optional.h:158
Optional & operator=(nullopt_t) FL_NOEXCEPT
Definition optional.h:189
Optional() FL_NOEXCEPT
Definition optional.h:154
Optional(Optional &&other) FL_NOEXCEPT
Definition optional.h:164
T && get() FL_NOEXCEPT
Definition optional.h:218
T && operator*() FL_NOEXCEPT
Definition optional.h:216
bool has_value() const FL_NOEXCEPT
Definition optional.h:171
bool operator!=(const Optional &other) const FL_NOEXCEPT
Definition optional.h:210
void reset() FL_NOEXCEPT
Definition optional.h:175
bool operator==(nullopt_t) const FL_NOEXCEPT
Definition optional.h:212
const T & operator*() const FL_NOEXCEPT
Definition optional.h:217
~Optional() FL_NOEXCEPT
Definition optional.h:168
const T * operator->() const FL_NOEXCEPT
Definition optional.h:223
bool empty() const FL_NOEXCEPT
Definition optional.h:170
const T & get() const FL_NOEXCEPT
Definition optional.h:219
Optional(nullopt_t) FL_NOEXCEPT
Definition optional.h:155
Optional(const Optional &) FL_NOEXCEPT=delete
T * ptr() FL_NOEXCEPT
Definition optional.h:172
T && value() FL_NOEXCEPT
Definition optional.h:226
const T & value() const FL_NOEXCEPT
Definition optional.h:227
bool operator!() const FL_NOEXCEPT
Definition optional.h:195
bool operator!=(nullopt_t) const FL_NOEXCEPT
Definition optional.h:213
Optional & operator=(Optional &&other) FL_NOEXCEPT
Definition optional.h:181
bool operator==(const Optional &other) const FL_NOEXCEPT
Definition optional.h:200
Optional & operator=(const Optional &) FL_NOEXCEPT=delete
bool operator()() const FL_NOEXCEPT
Definition optional.h:194
Optional & operator=(nullopt_t) FL_NOEXCEPT
Definition optional.h:62
~Optional() FL_NOEXCEPT
Definition optional.h:30
bool operator==(const T &value) const FL_NOEXCEPT
Definition optional.h:95
T * ptr() FL_NOEXCEPT
Definition optional.h:43
const T & operator*() const FL_NOEXCEPT
Definition optional.h:107
void swap(Optional &other) FL_NOEXCEPT
Definition optional.h:140
T & value() FL_NOEXCEPT
Definition optional.h:112
bool operator()() const FL_NOEXCEPT
Definition optional.h:77
bool empty() const FL_NOEXCEPT
Definition optional.h:41
bool operator==(const variant< TT, UU > &other) const FL_NOEXCEPT
Definition optional.h:127
const T * ptr() const FL_NOEXCEPT
Definition optional.h:44
const T & value() const FL_NOEXCEPT
Definition optional.h:113
T * operator->() FL_NOEXCEPT
Definition optional.h:108
void emplace(T &&value) FL_NOEXCEPT
Emplace with rvalue reference.
Definition optional.h:33
Optional(Optional &&other) FL_NOEXCEPT
Definition optional.h:26
bool operator!=(const Optional &other) const FL_NOEXCEPT
Definition optional.h:93
Optional(nullopt_t) FL_NOEXCEPT
Definition optional.h:24
T value_or(T &&default_value) const FL_NOEXCEPT
Definition optional.h:122
Optional & operator=(Optional &&other) FL_NOEXCEPT
Definition optional.h:55
void reset() FL_NOEXCEPT
Definition optional.h:46
const T * operator->() const FL_NOEXCEPT
Definition optional.h:109
T & operator*() FL_NOEXCEPT
Definition optional.h:106
Optional(const Optional &other) FL_NOEXCEPT
Definition optional.h:25
Optional & operator=(T &&value) FL_NOEXCEPT
Definition optional.h:72
bool operator!() const FL_NOEXCEPT
Definition optional.h:78
fl::variant< T, Empty > mValue
Definition optional.h:147
Optional() FL_NOEXCEPT
Definition optional.h:23
T value_or(const T &default_value) const FL_NOEXCEPT
Definition optional.h:117
bool operator!=(nullopt_t) const FL_NOEXCEPT
Definition optional.h:103
bool operator==(nullopt_t) const FL_NOEXCEPT
Definition optional.h:102
Optional(const T &value) FL_NOEXCEPT
Definition optional.h:28
bool operator==(const Optional &other) const FL_NOEXCEPT
Definition optional.h:83
bool has_value() const FL_NOEXCEPT
Definition optional.h:42
Optional & operator=(const T &value) FL_NOEXCEPT
Definition optional.h:67
void emplace(Args &&... args) FL_NOEXCEPT
Construct value in-place with variadic arguments.
Definition optional.h:37
Optional & operator=(const Optional &other) FL_NOEXCEPT
Definition optional.h:48
Optional(T &&value) FL_NOEXCEPT
Definition optional.h:29
constexpr T && forward(typename remove_reference< T >::type &t) FL_NOEXCEPT
Definition s16x16x4.h:234
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
Definition s16x16x4.h:28
constexpr int type_rank< T >::value
Optional< T > optional
Definition optional.h:16
optional< T > make_optional(const T &value) FL_NOEXCEPT
Definition optional.h:235
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
#define FL_NOEXCEPT