#pragma once // // Copyright (c) 2017 Martin Moene // // https://github.com/martinmoene/optional-bare // // This code is licensed under the MIT License (MIT). // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // Modified by Otto Winter on 18.05.18 #include namespace esphome { // type for nullopt struct nullopt_t { // NOLINT struct init {}; // NOLINT nullopt_t(init) {} }; // extra parenthesis to prevent the most vexing parse: const nullopt_t nullopt((nullopt_t::init())); // NOLINT // Simplistic optional: requires T to be default constructible, copyable. template class optional { // NOLINT private: using safe_bool = void (optional::*)() const; public: using value_type = T; optional() {} optional(nullopt_t) {} optional(T const &arg) : has_value_(true), value_(arg) {} // NOLINT template optional(optional const &other) : has_value_(other.has_value()), value_(other.value()) {} optional &operator=(nullopt_t) { reset(); return *this; } template optional &operator=(optional const &other) { has_value_ = other.has_value(); value_ = other.value(); return *this; } void swap(optional &rhs) { using std::swap; if (has_value() && rhs.has_value()) { swap(**this, *rhs); } else if (!has_value() && rhs.has_value()) { initialize(*rhs); rhs.reset(); } else if (has_value() && !rhs.has_value()) { rhs.initialize(**this); reset(); } } // observers value_type const *operator->() const { return &value_; } value_type *operator->() { return &value_; } value_type const &operator*() const { return value_; } value_type &operator*() { return value_; } operator safe_bool() const { return has_value() ? &optional::this_type_does_not_support_comparisons : nullptr; } bool has_value() const { return has_value_; } value_type const &value() const { return value_; } value_type &value() { return value_; } template value_type value_or(U const &v) const { return has_value() ? value() : static_cast(v); } // modifiers void reset() { has_value_ = false; } private: void this_type_does_not_support_comparisons() const {} // NOLINT template void initialize(V const &value) { // NOLINT value_ = value; has_value_ = true; } private: bool has_value_{false}; // NOLINT value_type value_; // NOLINT }; // Relational operators template inline bool operator==(optional const &x, optional const &y) { return bool(x) != bool(y) ? false : !bool(x) ? true : *x == *y; } template inline bool operator!=(optional const &x, optional const &y) { return !(x == y); } template inline bool operator<(optional const &x, optional const &y) { return (!y) ? false : (!x) ? true : *x < *y; } template inline bool operator>(optional const &x, optional const &y) { return (y < x); } template inline bool operator<=(optional const &x, optional const &y) { return !(y < x); } template inline bool operator>=(optional const &x, optional const &y) { return !(x < y); } // Comparison with nullopt template inline bool operator==(optional const &x, nullopt_t) { return (!x); } template inline bool operator==(nullopt_t, optional const &x) { return (!x); } template inline bool operator!=(optional const &x, nullopt_t) { return bool(x); } template inline bool operator!=(nullopt_t, optional const &x) { return bool(x); } template inline bool operator<(optional const &, nullopt_t) { return false; } template inline bool operator<(nullopt_t, optional const &x) { return bool(x); } template inline bool operator<=(optional const &x, nullopt_t) { return (!x); } template inline bool operator<=(nullopt_t, optional const &) { return true; } template inline bool operator>(optional const &x, nullopt_t) { return bool(x); } template inline bool operator>(nullopt_t, optional const &) { return false; } template inline bool operator>=(optional const &, nullopt_t) { return true; } template inline bool operator>=(nullopt_t, optional const &x) { return (!x); } // Comparison with T template inline bool operator==(optional const &x, U const &v) { return bool(x) ? *x == v : false; } template inline bool operator==(U const &v, optional const &x) { return bool(x) ? v == *x : false; } template inline bool operator!=(optional const &x, U const &v) { return bool(x) ? *x != v : true; } template inline bool operator!=(U const &v, optional const &x) { return bool(x) ? v != *x : true; } template inline bool operator<(optional const &x, U const &v) { return bool(x) ? *x < v : true; } template inline bool operator<(U const &v, optional const &x) { return bool(x) ? v < *x : false; } template inline bool operator<=(optional const &x, U const &v) { return bool(x) ? *x <= v : true; } template inline bool operator<=(U const &v, optional const &x) { return bool(x) ? v <= *x : false; } template inline bool operator>(optional const &x, U const &v) { return bool(x) ? *x > v : false; } template inline bool operator>(U const &v, optional const &x) { return bool(x) ? v > *x : true; } template inline bool operator>=(optional const &x, U const &v) { return bool(x) ? *x >= v : false; } template inline bool operator>=(U const &v, optional const &x) { return bool(x) ? v >= *x : true; } // Specialized algorithms template void swap(optional &x, optional &y) { x.swap(y); } // Convenience function to create an optional. template inline optional make_optional(T const &v) { return optional(v); } } // namespace esphome