ESPHome  2024.12.2
optional.h
Go to the documentation of this file.
1 #pragma once
2 //
3 // Copyright (c) 2017 Martin Moene
4 //
5 // https://github.com/martinmoene/optional-bare
6 //
7 // This code is licensed under the MIT License (MIT).
8 //
9 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
13 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
15 // THE SOFTWARE.
16 //
17 // Modified by Otto Winter on 18.05.18
18 
19 #include <algorithm>
20 
21 namespace esphome {
22 
23 // type for nullopt
24 
25 struct nullopt_t { // NOLINT
26  struct init {}; // NOLINT
27  nullopt_t(init /*unused*/) {}
28 };
29 
30 // extra parenthesis to prevent the most vexing parse:
31 
32 const nullopt_t nullopt((nullopt_t::init())); // NOLINT
33 
34 // Simplistic optional: requires T to be default constructible, copyable.
35 
36 template<typename T> class optional { // NOLINT
37  private:
38  using safe_bool = void (optional::*)() const;
39 
40  public:
41  using value_type = T;
42 
43  optional() {}
44 
45  optional(nullopt_t /*unused*/) {}
46 
47  optional(T const &arg) : has_value_(true), value_(arg) {} // NOLINT
48 
49  template<class U> optional(optional<U> const &other) : has_value_(other.has_value()), value_(other.value()) {}
50 
51  optional &operator=(nullopt_t /*unused*/) {
52  reset();
53  return *this;
54  }
55 
56  template<class U> optional &operator=(optional<U> const &other) {
57  has_value_ = other.has_value();
58  value_ = other.value();
59  return *this;
60  }
61 
62  void swap(optional &rhs) noexcept {
63  using std::swap;
64  if (has_value() && rhs.has_value()) {
65  swap(**this, *rhs);
66  } else if (!has_value() && rhs.has_value()) {
67  initialize(*rhs);
68  rhs.reset();
69  } else if (has_value() && !rhs.has_value()) {
70  rhs.initialize(**this);
71  reset();
72  }
73  }
74 
75  // observers
76 
77  value_type const *operator->() const { return &value_; }
78 
79  value_type *operator->() { return &value_; }
80 
81  value_type const &operator*() const { return value_; }
82 
83  value_type &operator*() { return value_; }
84 
85  operator safe_bool() const { return has_value() ? &optional::this_type_does_not_support_comparisons : nullptr; }
86 
87  bool has_value() const { return has_value_; }
88 
89  value_type const &value() const { return value_; }
90 
91  value_type &value() { return value_; }
92 
93  template<class U> value_type value_or(U const &v) const { return has_value() ? value() : static_cast<value_type>(v); }
94 
95  // modifiers
96 
97  void reset() { has_value_ = false; }
98 
99  private:
100  void this_type_does_not_support_comparisons() const {} // NOLINT
101 
102  template<typename V> void initialize(V const &value) { // NOLINT
103  value_ = value;
104  has_value_ = true;
105  }
106 
107  bool has_value_{false}; // NOLINT
108  value_type value_; // NOLINT
109 };
110 
111 // Relational operators
112 
113 template<typename T, typename U> inline bool operator==(optional<T> const &x, optional<U> const &y) {
114  return bool(x) != bool(y) ? false : !bool(x) ? true : *x == *y;
115 }
116 
117 template<typename T, typename U> inline bool operator!=(optional<T> const &x, optional<U> const &y) {
118  return !(x == y);
119 }
120 
121 template<typename T, typename U> inline bool operator<(optional<T> const &x, optional<U> const &y) {
122  return (!y) ? false : (!x) ? true : *x < *y;
123 }
124 
125 template<typename T, typename U> inline bool operator>(optional<T> const &x, optional<U> const &y) { return (y < x); }
126 
127 template<typename T, typename U> inline bool operator<=(optional<T> const &x, optional<U> const &y) { return !(y < x); }
128 
129 template<typename T, typename U> inline bool operator>=(optional<T> const &x, optional<U> const &y) { return !(x < y); }
130 
131 // Comparison with nullopt
132 
133 template<typename T> inline bool operator==(optional<T> const &x, nullopt_t /*unused*/) { return (!x); }
134 
135 template<typename T> inline bool operator==(nullopt_t /*unused*/, optional<T> const &x) { return (!x); }
136 
137 template<typename T> inline bool operator!=(optional<T> const &x, nullopt_t /*unused*/) { return bool(x); }
138 
139 template<typename T> inline bool operator!=(nullopt_t /*unused*/, optional<T> const &x) { return bool(x); }
140 
141 template<typename T> inline bool operator<(optional<T> const & /*unused*/, nullopt_t /*unused*/) { return false; }
142 
143 template<typename T> inline bool operator<(nullopt_t /*unused*/, optional<T> const &x) { return bool(x); }
144 
145 template<typename T> inline bool operator<=(optional<T> const &x, nullopt_t /*unused*/) { return (!x); }
146 
147 template<typename T> inline bool operator<=(nullopt_t /*unused*/, optional<T> const & /*unused*/) { return true; }
148 
149 template<typename T> inline bool operator>(optional<T> const &x, nullopt_t /*unused*/) { return bool(x); }
150 
151 template<typename T> inline bool operator>(nullopt_t /*unused*/, optional<T> const & /*unused*/) { return false; }
152 
153 template<typename T> inline bool operator>=(optional<T> const & /*unused*/, nullopt_t /*unused*/) { return true; }
154 
155 template<typename T> inline bool operator>=(nullopt_t /*unused*/, optional<T> const &x) { return (!x); }
156 
157 // Comparison with T
158 
159 template<typename T, typename U> inline bool operator==(optional<T> const &x, U const &v) {
160  return bool(x) ? *x == v : false;
161 }
162 
163 template<typename T, typename U> inline bool operator==(U const &v, optional<T> const &x) {
164  return bool(x) ? v == *x : false;
165 }
166 
167 template<typename T, typename U> inline bool operator!=(optional<T> const &x, U const &v) {
168  return bool(x) ? *x != v : true;
169 }
170 
171 template<typename T, typename U> inline bool operator!=(U const &v, optional<T> const &x) {
172  return bool(x) ? v != *x : true;
173 }
174 
175 template<typename T, typename U> inline bool operator<(optional<T> const &x, U const &v) {
176  return bool(x) ? *x < v : true;
177 }
178 
179 template<typename T, typename U> inline bool operator<(U const &v, optional<T> const &x) {
180  return bool(x) ? v < *x : false;
181 }
182 
183 template<typename T, typename U> inline bool operator<=(optional<T> const &x, U const &v) {
184  return bool(x) ? *x <= v : true;
185 }
186 
187 template<typename T, typename U> inline bool operator<=(U const &v, optional<T> const &x) {
188  return bool(x) ? v <= *x : false;
189 }
190 
191 template<typename T, typename U> inline bool operator>(optional<T> const &x, U const &v) {
192  return bool(x) ? *x > v : false;
193 }
194 
195 template<typename T, typename U> inline bool operator>(U const &v, optional<T> const &x) {
196  return bool(x) ? v > *x : true;
197 }
198 
199 template<typename T, typename U> inline bool operator>=(optional<T> const &x, U const &v) {
200  return bool(x) ? *x >= v : false;
201 }
202 
203 template<typename T, typename U> inline bool operator>=(U const &v, optional<T> const &x) {
204  return bool(x) ? v >= *x : true;
205 }
206 
207 // Specialized algorithms
208 
209 template<typename T> void swap(optional<T> &x, optional<T> &y) noexcept { x.swap(y); }
210 
211 // Convenience function to create an optional.
212 
213 template<typename T> inline optional<T> make_optional(T const &v) { return optional<T>(v); }
214 
215 } // namespace esphome
optional< T > make_optional(T const &v)
Definition: optional.h:213
value_type const & value() const
Definition: optional.h:89
optional(T const &arg)
Definition: optional.h:47
uint16_t x
Definition: tt21100.cpp:17
value_type const & operator*() const
Definition: optional.h:81
bool has_value() const
Definition: optional.h:87
uint16_t y
Definition: tt21100.cpp:18
value_type & value()
Definition: optional.h:91
const nullopt_t nullopt((nullopt_t::init()))
void swap(optional &rhs) noexcept
Definition: optional.h:62
value_type const * operator->() const
Definition: optional.h:77
bool operator>(optional< T > const &x, optional< U > const &y)
Definition: optional.h:125
optional(nullopt_t)
Definition: optional.h:45
bool operator>=(optional< T > const &x, optional< U > const &y)
Definition: optional.h:129
value_type & operator*()
Definition: optional.h:83
optional & operator=(nullopt_t)
Definition: optional.h:51
bool operator<=(optional< T > const &x, optional< U > const &y)
Definition: optional.h:127
uint16_t reset
Definition: ina226.h:39
bool operator!=(optional< T > const &x, optional< U > const &y)
Definition: optional.h:117
bool operator<(optional< T > const &x, optional< U > const &y)
Definition: optional.h:121
bool operator==(optional< T > const &x, optional< U > const &y)
Definition: optional.h:113
value_type * operator->()
Definition: optional.h:79
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
optional(optional< U > const &other)
Definition: optional.h:49
optional & operator=(optional< U > const &other)
Definition: optional.h:56
value_type value_or(U const &v) const
Definition: optional.h:93
void swap(optional< T > &x, optional< T > &y) noexcept
Definition: optional.h:209