File indexing completed on 2024-06-23 04:38:07

0001 // SPDX-FileCopyrightText: 2020 Henri Chain <henri.chain@enioka.com>
0002 // SPDX-FileCopyrightText: 2020 Kevin Ottens <kevin.ottens@enioka.com>
0003 //
0004 // SPDX-License-Identifier: LGPL-2.1-or-later
0005 
0006 #ifndef OPTIONAL_H
0007 #define OPTIONAL_H
0008 
0009 #include <memory>
0010 #include <type_traits>
0011 
0012 namespace KCGroups
0013 {
0014 template<typename T>
0015 class optional
0016 {
0017     static_assert(!std::is_reference<T>::value, "optional doesn't support references");
0018 
0019 public:
0020     optional() = default;
0021 
0022     optional(const T &v)
0023         : m_value(v)
0024         , m_hasValue(true)
0025     {
0026     }
0027 
0028     optional(T &&v)
0029         : m_value(std::move(v))
0030         , m_hasValue(true)
0031     {
0032     }
0033 
0034     explicit operator bool() const noexcept
0035     {
0036         return m_hasValue;
0037     }
0038 
0039     T const &operator*() const noexcept
0040     {
0041         return m_value;
0042     }
0043 
0044     T operator*()
0045     {
0046         return m_value;
0047     }
0048 
0049     optional &operator=(const T &v) noexcept
0050     {
0051         m_hasValue = true;
0052         m_value = v;
0053         return *this;
0054     }
0055 
0056     optional &operator=(T &&v) noexcept
0057     {
0058         m_hasValue = true;
0059         m_value = std::move(v);
0060         return *this;
0061     }
0062 
0063     void reset()
0064     {
0065         if (m_hasValue) {
0066             m_value.~T();
0067             m_hasValue = false;
0068         }
0069     }
0070 
0071 private:
0072     T m_value = {};
0073     bool m_hasValue = false;
0074 }; // class optional
0075 
0076 template<typename T, typename U>
0077 bool operator==(const optional<T> &lhs, const optional<U> &rhs) noexcept
0078 {
0079     const auto l = static_cast<bool>(lhs), r = static_cast<bool>(rhs);
0080     return l && r ? *lhs == *rhs : !l && !r;
0081 }
0082 
0083 template<typename T, typename U>
0084 bool operator!=(const optional<T> &lhs, const optional<U> &rhs) noexcept
0085 {
0086     return !(lhs == rhs);
0087 }
0088 
0089 template<typename T, typename U>
0090 bool operator==(const optional<T> &lhs, const U &rhs) noexcept
0091 {
0092     return static_cast<bool>(lhs) && *lhs == rhs;
0093 }
0094 
0095 template<typename T, typename U>
0096 bool operator!=(const optional<T> &lhs, const U &rhs) noexcept
0097 {
0098     return !(lhs == rhs);
0099 }
0100 
0101 template<typename T, typename U>
0102 bool operator==(const T &lhs, const optional<T> &rhs) noexcept
0103 {
0104     return rhs == lhs;
0105 }
0106 
0107 template<typename T, typename U>
0108 bool operator!=(const T &lhs, const optional<T> &rhs) noexcept
0109 {
0110     return !(lhs == rhs);
0111 }
0112 }
0113 #endif // OPTIONAL_H