ESPHome  1.15.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 namespace esphome {
20 
21 // type for nullopt
22 
23 struct nullopt_t { // NOLINT
24  struct init {}; // NOLINT
26 };
27 
28 // extra parenthesis to prevent the most vexing parse:
29 
30 const nullopt_t nullopt((nullopt_t::init())); // NOLINT
31 
32 // Simplistic optional: requires T to be default constructible, copyable.
33 
34 template<typename T> class optional { // NOLINT
35  private:
36  using safe_bool = void (optional::*)() const;
37 
38  public:
39  using value_type = T;
40 
41  optional() {}
42 
44 
45  optional(T const &arg) : has_value_(true), value_(arg) {}
46 
47  template<class U> optional(optional<U> const &other) : has_value_(other.has_value()), value_(other.value()) {}
48 
50  reset();
51  return *this;
52  }
53 
54  template<class U> optional &operator=(optional<U> const &other) {
55  has_value_ = other.has_value();
56  value_ = other.value();
57  return *this;
58  }
59 
60  void swap(optional &rhs) {
61  using std::swap;
62  if (has_value() && rhs.has_value()) {
63  swap(**this, *rhs);
64  } else if (!has_value() && rhs.has_value()) {
65  initialize(*rhs);
66  rhs.reset();
67  } else if (has_value() && !rhs.has_value()) {
68  rhs.initialize(**this);
69  reset();
70  }
71  }
72 
73  // observers
74 
75  value_type const *operator->() const { return &value_; }
76 
77  value_type *operator->() { return &value_; }
78 
79  value_type const &operator*() const { return value_; }
80 
81  value_type &operator*() { return value_; }
82 
83  operator safe_bool() const { return has_value() ? &optional::this_type_does_not_support_comparisons : nullptr; }
84 
85  bool has_value() const { return has_value_; }
86 
87  value_type const &value() const { return value_; }
88 
89  value_type &value() { return value_; }
90 
91  template<class U> value_type value_or(U const &v) const { return has_value() ? value() : static_cast<value_type>(v); }
92 
93  // modifiers
94 
95  void reset() { has_value_ = false; }
96 
97  private:
98  void this_type_does_not_support_comparisons() const {} // NOLINT
99 
100  template<typename V> void initialize(V const &value) { // NOLINT
101  value_ = value;
102  has_value_ = true;
103  }
104 
105  private:
106  bool has_value_{false}; // NOLINT
107  value_type value_; // NOLINT
108 };
109 
110 // Relational operators
111 
112 template<typename T, typename U> inline bool operator==(optional<T> const &x, optional<U> const &y) {
113  return bool(x) != bool(y) ? false : !bool(x) ? true : *x == *y;
114 }
115 
116 template<typename T, typename U> inline bool operator!=(optional<T> const &x, optional<U> const &y) {
117  return !(x == y);
118 }
119 
120 template<typename T, typename U> inline bool operator<(optional<T> const &x, optional<U> const &y) {
121  return (!y) ? false : (!x) ? true : *x < *y;
122 }
123 
124 template<typename T, typename U> inline bool operator>(optional<T> const &x, optional<U> const &y) { return (y < x); }
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 !(x < y); }
129 
130 // Comparison with nullopt
131 
132 template<typename T> inline bool operator==(optional<T> const &x, nullopt_t) { return (!x); }
133 
134 template<typename T> inline bool operator==(nullopt_t, optional<T> const &x) { return (!x); }
135 
136 template<typename T> inline bool operator!=(optional<T> const &x, nullopt_t) { return bool(x); }
137 
138 template<typename T> inline bool operator!=(nullopt_t, optional<T> const &x) { return bool(x); }
139 
140 template<typename T> inline bool operator<(optional<T> const &, nullopt_t) { return false; }
141 
142 template<typename T> inline bool operator<(nullopt_t, optional<T> const &x) { return bool(x); }
143 
144 template<typename T> inline bool operator<=(optional<T> const &x, nullopt_t) { return (!x); }
145 
146 template<typename T> inline bool operator<=(nullopt_t, optional<T> const &) { return true; }
147 
148 template<typename T> inline bool operator>(optional<T> const &x, nullopt_t) { return bool(x); }
149 
150 template<typename T> inline bool operator>(nullopt_t, optional<T> const &) { return false; }
151 
152 template<typename T> inline bool operator>=(optional<T> const &, nullopt_t) { return true; }
153 
154 template<typename T> inline bool operator>=(nullopt_t, optional<T> const &x) { return (!x); }
155 
156 // Comparison with T
157 
158 template<typename T, typename U> inline bool operator==(optional<T> const &x, U const &v) {
159  return bool(x) ? *x == v : false;
160 }
161 
162 template<typename T, typename U> inline bool operator==(U const &v, optional<T> const &x) {
163  return bool(x) ? v == *x : false;
164 }
165 
166 template<typename T, typename U> inline bool operator!=(optional<T> const &x, U const &v) {
167  return bool(x) ? *x != v : true;
168 }
169 
170 template<typename T, typename U> inline bool operator!=(U const &v, optional<T> const &x) {
171  return bool(x) ? v != *x : true;
172 }
173 
174 template<typename T, typename U> inline bool operator<(optional<T> const &x, U const &v) {
175  return bool(x) ? *x < v : true;
176 }
177 
178 template<typename T, typename U> inline bool operator<(U const &v, optional<T> const &x) {
179  return bool(x) ? v < *x : false;
180 }
181 
182 template<typename T, typename U> inline bool operator<=(optional<T> const &x, U const &v) {
183  return bool(x) ? *x <= v : true;
184 }
185 
186 template<typename T, typename U> inline bool operator<=(U const &v, optional<T> const &x) {
187  return bool(x) ? v <= *x : false;
188 }
189 
190 template<typename T, typename U> inline bool operator>(optional<T> const &x, U const &v) {
191  return bool(x) ? *x > v : false;
192 }
193 
194 template<typename T, typename U> inline bool operator>(U const &v, optional<T> const &x) {
195  return bool(x) ? v > *x : true;
196 }
197 
198 template<typename T, typename U> inline bool operator>=(optional<T> const &x, U const &v) {
199  return bool(x) ? *x >= v : false;
200 }
201 
202 template<typename T, typename U> inline bool operator>=(U const &v, optional<T> const &x) {
203  return bool(x) ? v >= *x : true;
204 }
205 
206 // Specialized algorithms
207 
208 template<typename T> void swap(optional<T> &x, optional<T> &y) { x.swap(y); }
209 
210 // Convenience function to create an optional.
211 
212 template<typename T> inline optional<T> make_optional(T const &v) { return optional<T>(v); }
213 
214 } // namespace esphome
optional< T > make_optional(T const &v)
Definition: optional.h:212
value_type const & value() const
Definition: optional.h:87
optional(T const &arg)
Definition: optional.h:45
value_type const & operator*() const
Definition: optional.h:79
bool has_value() const
Definition: optional.h:85
value_type & value()
Definition: optional.h:89
const nullopt_t nullopt((nullopt_t::init()))
value_type const * operator->() const
Definition: optional.h:75
bool operator>(optional< T > const &x, optional< U > const &y)
Definition: optional.h:124
optional(nullopt_t)
Definition: optional.h:43
bool operator>=(optional< T > const &x, optional< U > const &y)
Definition: optional.h:128
value_type & operator*()
Definition: optional.h:81
optional & operator=(nullopt_t)
Definition: optional.h:49
bool operator!=(optional< T > const &x, optional< U > const &y)
Definition: optional.h:116
void swap(optional &rhs)
Definition: optional.h:60
void swap(optional< T > &x, optional< T > &y)
Definition: optional.h:208
bool operator==(optional< T > const &x, optional< U > const &y)
Definition: optional.h:112
value_type * operator->()
Definition: optional.h:77
Definition: a4988.cpp:4
optional(optional< U > const &other)
Definition: optional.h:47
optional & operator=(optional< U > const &other)
Definition: optional.h:54
value_type value_or(U const &v) const
Definition: optional.h:91