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