cmake: avoid de-duplication of user's CXXFLAGS
[quassel.git] / src / common / types.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2022 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20
21 #pragma once
22
23 #include <type_traits>
24
25 #include <QDataStream>
26 #include <QDebug>
27 #include <QHostAddress>
28 #include <QString>
29 #include <QTextStream>
30 #include <QVariant>
31
32 class SignedId
33 {
34 protected:
35     qint32 id;
36
37 public:
38     inline SignedId(int _id = 0) { id = _id; }
39     inline qint32 toInt() const { return id; }
40     inline bool isValid() const { return id > 0; }
41
42     inline bool operator==(const SignedId& other) const { return id == other.id; }
43     inline bool operator!=(const SignedId& other) const { return id != other.id; }
44     inline bool operator<(const SignedId& other) const { return id < other.id; }
45     inline bool operator<=(const SignedId& other) const { return id <= other.id; }
46     inline bool operator>(const SignedId& other) const { return id > other.id; }
47     inline bool operator>=(const SignedId& other) const { return id >= other.id; }
48     inline bool operator==(int i) const { return id == i; }
49     inline bool operator!=(int i) const { return id != i; }
50     inline bool operator<(int i) const { return id < i; }
51     inline bool operator>(int i) const { return id > i; }
52     inline bool operator<=(int i) const { return id <= i; }
53
54     inline SignedId operator++(int)
55     {
56         id++;
57         return *this;
58     }
59     // inline operator int() const { return toInt(); } // no automatic conversion!
60
61     friend QDataStream& operator>>(QDataStream& in, SignedId& signedId);
62 };
63
64 inline QDataStream& operator<<(QDataStream& out, const SignedId& signedId)
65 {
66     out << signedId.toInt();
67     return out;
68 }
69 inline QDataStream& operator>>(QDataStream& in, SignedId& signedId)
70 {
71     in >> signedId.id;
72     return in;
73 }
74 inline QTextStream& operator<<(QTextStream& out, const SignedId& signedId)
75 {
76     out << QString::number(signedId.toInt());
77     return out;
78 }
79 inline QDebug operator<<(QDebug dbg, const SignedId& signedId)
80 {
81     dbg.space() << signedId.toInt();
82     return dbg;
83 }
84 inline uint qHash(const SignedId& id)
85 {
86     return qHash(id.toInt());
87 }
88
89 class SignedId64
90 {
91 protected:
92     qint64 id;
93
94 public:
95     inline SignedId64(qint64 _id = 0) { id = _id; }
96     inline qint64 toQint64() const { return id; }
97     inline bool isValid() const { return id > 0; }
98
99     inline bool operator==(const SignedId64& other) const { return id == other.id; }
100     inline bool operator!=(const SignedId64& other) const { return id != other.id; }
101     inline bool operator<(const SignedId64& other) const { return id < other.id; }
102     inline bool operator<=(const SignedId64& other) const { return id <= other.id; }
103     inline bool operator>(const SignedId64& other) const { return id > other.id; }
104     inline bool operator>=(const SignedId64& other) const { return id >= other.id; }
105     inline bool operator==(qint64 i) const { return id == i; }
106     inline bool operator!=(qint64 i) const { return id != i; }
107     inline bool operator<(qint64 i) const { return id < i; }
108     inline bool operator>(qint64 i) const { return id > i; }
109     inline bool operator<=(qint64 i) const { return id <= i; }
110
111     inline SignedId64 operator++(int)
112     {
113         id++;
114         return *this;
115     }
116     // inline operator int() const { return toQint64(); } // no automatic conversion!
117
118     friend QDataStream& operator>>(QDataStream& in, SignedId64& signedId);
119 };
120
121 QDataStream& operator<<(QDataStream& out, const SignedId64& signedId);
122 QDataStream& operator>>(QDataStream& in, SignedId64& signedId);
123 inline QTextStream& operator<<(QTextStream& out, const SignedId64& signedId)
124 {
125     out << QString::number(signedId.toQint64());
126     return out;
127 }
128 inline QDebug operator<<(QDebug dbg, const SignedId64& signedId)
129 {
130     dbg.space() << signedId.toQint64();
131     return dbg;
132 }
133 inline uint qHash(const SignedId64& id)
134 {
135     return qHash(id.toQint64());
136 }
137
138 struct UserId : public SignedId
139 {
140     inline UserId(int _id = 0)
141         : SignedId(_id)
142     {}
143     // inline operator QVariant() const { return QVariant::fromValue(*this); }  // no automatic conversion!
144 };
145
146 struct MsgId : public SignedId64
147 {
148     inline MsgId(qint64 _id = 0)
149         : SignedId64(_id)
150     {}
151     // inline operator QVariant() const { return QVariant::fromValue(*this); }
152 };
153
154 struct BufferId : public SignedId
155 {
156     inline BufferId(int _id = 0)
157         : SignedId(_id)
158     {}
159     // inline operator QVariant() const { return QVariant::fromValue(*this); }
160 };
161
162 struct NetworkId : public SignedId
163 {
164     inline NetworkId(int _id = 0)
165         : SignedId(_id)
166     {}
167     // inline operator QVariant() const { return QVariant::fromValue(*this); }
168 };
169
170 struct IdentityId : public SignedId
171 {
172     inline IdentityId(int _id = 0)
173         : SignedId(_id)
174     {}
175     // inline operator QVariant() const { return QVariant::fromValue(*this); }
176 };
177
178 struct AccountId : public SignedId
179 {
180     inline AccountId(int _id = 0)
181         : SignedId(_id)
182     {}
183 };
184
185 Q_DECLARE_METATYPE(UserId)
186 Q_DECLARE_METATYPE(MsgId)
187 Q_DECLARE_METATYPE(BufferId)
188 Q_DECLARE_METATYPE(NetworkId)
189 Q_DECLARE_METATYPE(IdentityId)
190 Q_DECLARE_METATYPE(AccountId)
191
192 Q_DECLARE_METATYPE(QHostAddress)
193
194 // a few typedefs
195 using MsgIdList = QList<MsgId>;
196 using BufferIdList = QList<BufferId>;
197
198 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
199 /**
200  * Catch-all stream serialization operator for enum types.
201  *
202  * @param[in,out] out   Stream to serialize to
203  * @param[in]     value Value to serialize
204  * @returns A reference to the stream
205  */
206 template<typename T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
207 QDataStream& operator<<(QDataStream& out, T value)
208 {
209     out << static_cast<typename std::underlying_type<T>::type>(value);
210     return out;
211 }
212
213 /**
214  * Catch-all stream serialization operator for enum types.
215  *
216  * @param[in,out] in    Stream to deserialize from
217  * @param[out]    value Value to deserialize into
218  * @returns A reference to the stream
219  */
220 template<typename T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
221 QDataStream& operator>>(QDataStream& in, T& value)
222 {
223     typename std::underlying_type<T>::type v;
224     in >> v;
225     value = static_cast<T>(v);
226     return in;
227 }
228 #endif
229
230 // STL-compliant hash functor for Qt types
231 template<typename T>
232 struct Hash
233 {
234     uint operator()(const T& t) const
235     {
236         return qHash(t);
237     }
238 };
239
240 // Exceptions
241
242 /**
243  * Thrown during initialization to enforce exiting the application before the event loop is started
244  */
245 struct ExitException
246 {
247     int exitCode;
248     QString errorString;
249
250     ExitException(int code = EXIT_FAILURE, QString error = {})
251         : exitCode(code)
252         , errorString(std::move(error))
253     {}
254 };