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 OPTIONALGADGET_H 0007 #define OPTIONALGADGET_H 0008 0009 #ifdef STD_OPTIONAL_AVAILABLE 0010 #include <optional> 0011 #endif 0012 0013 #ifdef __cpp_lib_optional 0014 namespace KCGroups 0015 { 0016 template<typename T> 0017 using optional = std::optional<T>; 0018 } 0019 #else 0020 #include "optional.h" 0021 #endif 0022 0023 #define OPTIONAL_GADGET(T, name) \ 0024 /** \ 0025 @brief An optional T. \ 0026 The parameterless constructor creates a name without value. \n \ 0027 Use name(const T &val) to create a name with a value. \n \ 0028 Can be implicitly converted to T (undefined behavior when no value) and to bool (same has hasValue()) \ 0029 */ \ 0030 class KCGROUPS_EXPORT name : public KCGroups::optional<T> \ 0031 { \ 0032 Q_GADGET \ 0033 \ 0034 /** \ 0035 @brief The underlying T value. Returns a default T if hasValue() is false. \n \ 0036 Has a reset() method to remove the value, which can be reached in QML via x.value = undefined \ 0037 @accessors getValue(), setValue(), reset() \ 0038 */ \ 0039 Q_PROPERTY(T value READ getValue WRITE setValue RESET reset) \ 0040 \ 0041 /** \ 0042 @brief Whether there is currently a value defined \ 0043 @accessors hasValue() \ 0044 */ \ 0045 Q_PROPERTY(bool hasValue READ hasValue) \ 0046 \ 0047 public: \ 0048 /** \ 0049 The underlying value type. Equal to T \ 0050 */ \ 0051 using value_type = T; \ 0052 \ 0053 using KCGroups::optional<T>::optional; \ 0054 \ 0055 /** \ 0056 @brief get value or default \ 0057 @return underlying value if hasValue() is true, else default T value \ 0058 */ \ 0059 T getValue() \ 0060 { \ 0061 return *this ? **this : T(); \ 0062 } \ 0063 \ 0064 /** \ 0065 @brief set a T value \ 0066 @param val: the value to set \ 0067 */ \ 0068 void setValue(const T &val) \ 0069 { \ 0070 *reinterpret_cast<KCGroups::optional<T> *>(this) = val; \ 0071 } \ 0072 \ 0073 /** \ 0074 @brief whether a value is currently set \ 0075 @return true if a value is present, false otherwise \ 0076 */ \ 0077 bool hasValue() \ 0078 { \ 0079 return static_cast<bool>(*this); \ 0080 } \ 0081 }; \ 0082 \ 0083 inline bool operator==(const name &lhs, const name &rhs) \ 0084 { \ 0085 return static_cast<KCGroups::optional<typename name::value_type>>(lhs) == \ 0086 static_cast<KCGroups::optional<typename name::value_type>>(rhs); \ 0087 } \ 0088 \ 0089 inline bool operator!=(const name &lhs, const name &rhs) \ 0090 { \ 0091 return static_cast<KCGroups::optional<typename name::value_type>>(lhs) != \ 0092 static_cast<KCGroups::optional<typename name::value_type>>(rhs); \ 0093 } \ 0094 \ 0095 template<typename U> \ 0096 bool operator==(const name &lhs, const KCGroups::optional<U> &rhs) \ 0097 { \ 0098 return static_cast<KCGroups::optional<typename name::value_type>>(lhs) == rhs; \ 0099 } \ 0100 \ 0101 template<typename U> \ 0102 bool operator!=(const name &lhs, const KCGroups::optional<U> &rhs) \ 0103 { \ 0104 return static_cast<KCGroups::optional<typename name::value_type>>(lhs) != rhs; \ 0105 } \ 0106 \ 0107 template<typename T> \ 0108 bool operator==(const KCGroups::optional<T> &lhs, const name &rhs) \ 0109 { \ 0110 return lhs == static_cast<KCGroups::optional<typename name::value_type>>(rhs); \ 0111 } \ 0112 \ 0113 template<typename T> \ 0114 bool operator!=(const KCGroups::optional<T> &lhs, const name &rhs) \ 0115 { \ 0116 return lhs != static_cast<KCGroups::optional<typename name::value_type>>(rhs); \ 0117 } \ 0118 \ 0119 Q_DECLARE_METATYPE(name) \ 0120 static_assert(true, "") 0121 0122 #endif // OPTIONALGADGET_H