ESPHome  2021.11.3
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
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 
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 
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) {
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  private:
108  bool has_value_{false}; // NOLINT
109  value_type value_; // NOLINT
110 };
111 
112 // Relational operators
113 
114 template<typename T, typename U> inline bool operator==(optional<T> const &x, optional<U> const &y) {
115  return bool(x) != bool(y) ? false : !bool(x) ? true : *x == *y;
116 }
117 
118 template<typename T, typename U> inline bool operator!=(optional<T> const &x, optional<U> const &y) {
119  return !(x == y);
120 }
121 
122 template<typename T, typename U> inline bool operator<(optional<T> const &x, optional<U> const &y) {
123  return (!y) ? false : (!x) ? true : *x < *y;
124 }
125 
126 template<typename T, typename U> inline bool operator>(optional<T> const &x, optional<U> const &y) { return (y < x); }
127 
128 template<typename T, typename U> inline bool operator<=(optional<T> const &x, optional<U> const &y) { return !(y < x); }
129 
130 template<typename T, typename U> inline bool operator>=(optional<T> const &x, optional<U> const &y) { return !(x < y); }
131 
132 // Comparison with nullopt
133 
134 template<typename T> inline bool operator==(optional<T> const &x, nullopt_t) { return (!x); }
135 
136 template<typename T> inline bool operator==(nullopt_t, optional<T> const &x) { return (!x); }
137 
138 template<typename T> inline bool operator!=(optional<T> const &x, nullopt_t) { return bool(x); }
139 
140 template<typename T> inline bool operator!=(nullopt_t, optional<T> const &x) { return bool(x); }
141 
142 template<typename T> inline bool operator<(optional<T> const &, nullopt_t) { return false; }
143 
144 template<typename T> inline bool operator<(nullopt_t, optional<T> const &x) { return bool(x); }
145 
146 template<typename T> inline bool operator<=(optional<T> const &x, nullopt_t) { return (!x); }
147 
148 template<typename T> inline bool operator<=(nullopt_t, optional<T> const &) { return true; }
149 
150 template<typename T> inline bool operator>(optional<T> const &x, nullopt_t) { return bool(x); }
151 
152 template<typename T> inline bool operator>(nullopt_t, optional<T> const &) { return false; }
153 
154 template<typename T> inline bool operator>=(optional<T> const &, nullopt_t) { return true; }
155 
156 template<typename T> inline bool operator>=(nullopt_t, optional<T> const &x) { return (!x); }
157 
158 // Comparison with T
159 
160 template<typename T, typename U> inline bool operator==(optional<T> const &x, U const &v) {
161  return bool(x) ? *x == v : false;
162 }
163 
164 template<typename T, typename U> inline bool operator==(U const &v, optional<T> const &x) {
165  return bool(x) ? v == *x : false;
166 }
167 
168 template<typename T, typename U> inline bool operator!=(optional<T> const &x, U const &v) {
169  return bool(x) ? *x != v : true;
170 }
171 
172 template<typename T, typename U> inline bool operator!=(U const &v, optional<T> const &x) {
173  return bool(x) ? v != *x : true;
174 }
175 
176 template<typename T, typename U> inline bool operator<(optional<T> const &x, U const &v) {
177  return bool(x) ? *x < v : true;
178 }
179 
180 template<typename T, typename U> inline bool operator<(U const &v, optional<T> const &x) {
181  return bool(x) ? v < *x : false;
182 }
183 
184 template<typename T, typename U> inline bool operator<=(optional<T> const &x, U const &v) {
185  return bool(x) ? *x <= v : true;
186 }
187 
188 template<typename T, typename U> inline bool operator<=(U const &v, optional<T> const &x) {
189  return bool(x) ? v <= *x : false;
190 }
191 
192 template<typename T, typename U> inline bool operator>(optional<T> const &x, U const &v) {
193  return bool(x) ? *x > v : false;
194 }
195 
196 template<typename T, typename U> inline bool operator>(U const &v, optional<T> const &x) {
197  return bool(x) ? v > *x : true;
198 }
199 
200 template<typename T, typename U> inline bool operator>=(optional<T> const &x, U const &v) {
201  return bool(x) ? *x >= v : false;
202 }
203 
204 template<typename T, typename U> inline bool operator>=(U const &v, optional<T> const &x) {
205  return bool(x) ? v >= *x : true;
206 }
207 
208 // Specialized algorithms
209 
210 template<typename T> void swap(optional<T> &x, optional<T> &y) { x.swap(y); }
211 
212 // Convenience function to create an optional.
213 
214 template<typename T> inline optional<T> make_optional(T const &v) { return optional<T>(v); }
215 
216 } // namespace esphome
optional< T > make_optional(T const &v)
Definition: optional.h:214
value_type const & value() const
Definition: optional.h:89
optional(T const &arg)
Definition: optional.h:47
value_type const & operator*() const
Definition: optional.h:81
bool has_value() const
Definition: optional.h:87
value_type & value()
Definition: optional.h:91
const nullopt_t nullopt((nullopt_t::init()))
value_type const * operator->() const
Definition: optional.h:77
bool operator>(optional< T > const &x, optional< U > const &y)
Definition: optional.h:126
optional(nullopt_t)
Definition: optional.h:45
bool operator>=(optional< T > const &x, optional< U > const &y)
Definition: optional.h:130
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:118
void swap(optional &rhs)
Definition: optional.h:62
void swap(optional< T > &x, optional< T > &y)
Definition: optional.h:210
bool operator==(optional< T > const &x, optional< U > const &y)
Definition: optional.h:114
value_type * operator->()
Definition: optional.h:79
Library based on https://github.com/miguelbalboa/rfid and adapted to ESPHome by . ...
Definition: a4988.cpp:4
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