src/main.h

changeset 206
654661eab7f3
parent 205
1a4342d80de7
child 207
5315358a7d91
equal deleted inserted replaced
205:1a4342d80de7 206:654661eab7f3
1 /*
2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013 - 2020 Teemu Piippo
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 3 of the License, or
8 * (at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
17 */
18
19 #pragma once
20 #include <QString>
21 #include <QVector>
22 #include <QSet>
23 #include <QDebug>
24 #include <compare>
25 #include <memory>
26 #include "basics.h"
27 #include "utility.h"
28 #include "geometry.h"
29 #include "functional.h"
30
31 namespace settingGroups
32 {
33 // List of setting groups
34 constexpr char mainwindow[] = "mainwindow";
35 }
36
37 constexpr std::size_t operator""_z(const unsigned long long int x)
38 {
39 return static_cast<std::size_t>(x);
40 }
41
42 inline QString operator""_q(const char* string, const unsigned long int length)
43 {
44 Q_UNUSED(length)
45 return QString{string};
46 }
47
48 inline QPointF pointToPointF(const QPoint& point)
49 {
50 return {static_cast<qreal>(point.x()), static_cast<qreal>(point.y())};
51 }
52
53 inline QPoint pointFToPoint(const QPointF& point)
54 {
55 return {static_cast<int>(std::round(point.x())), static_cast<int>(std::round(point.y()))};
56 }
57
58 inline QSizeF sizeToSizeF(const QSize& size)
59 {
60 return {static_cast<qreal>(size.width()), static_cast<qreal>(size.height())};
61 }
62
63 /**
64 * \brief Hints to the specified vector that a certain amount of new elements are going to be added.
65 * \param vector vector to consider
66 * \param amount amount of new elements to expect
67 */
68 template<typename T>
69 void reserveMore(std::vector<T>& vector, std::size_t amount)
70 {
71 vector.reserve(vector.size() + amount);
72 }
73
74 inline QString vectorToString(const glm::vec2& vec)
75 {
76 return "(%1, %2)"_q
77 .arg(toDouble(vec.x))
78 .arg(toDouble(vec.y));
79 }
80
81 inline QString vectorToString(const glm::vec3& vec)
82 {
83 return "(%1, %2, %3)"_q
84 .arg(toDouble(vec.x))
85 .arg(toDouble(vec.y))
86 .arg(toDouble(vec.z));
87 }
88
89 inline QString vectorToString(const glm::vec4& vec)
90 {
91 return "(%1, %2, %3, %4)"_q
92 .arg(toDouble(vec.x))
93 .arg(toDouble(vec.y))
94 .arg(toDouble(vec.z))
95 .arg(toDouble(vec.w));
96 }
97
98 template<typename K, typename V>
99 struct KeyValuePair
100 {
101 K key;
102 V value;
103 };
104
105 template<typename K, typename V, typename IteratorType>
106 struct MapItemsIterator : IteratorType
107 {
108 template<typename... Ts>
109 MapItemsIterator(Ts&&... args) : IteratorType{args...} {}
110 auto operator*() const
111 {
112 return KeyValuePair<const K&, V&>{this->key(), this->value()};
113 }
114 };
115
116 template<typename K, typename V, typename MapType, typename IteratorType>
117 struct MapItems
118 {
119 MapType& map;
120 IteratorType begin()
121 {
122 return IteratorType(this->map.begin());
123 }
124
125 IteratorType end()
126 {
127 return IteratorType(this->map.end());
128 }
129 };
130
131 /*
132 * Python's dict.items for QMap: use in a for loop to iterate a map to
133 * get both keys and values. Iteration yields KeyValuePairs.
134 */
135 template<typename K, typename V>
136 auto items(const QMap<K, V>& map)
137 {
138 return MapItems<
139 const K&,
140 const V&,
141 const QMap<K, V>,
142 MapItemsIterator<K, const V, typename QMap<K, V>::const_iterator>
143 >{map};
144 }
145
146 template<typename K, typename V>
147 auto items(QMap<K, V>& map)
148 {
149 return MapItems<
150 const K&,
151 V&,
152 QMap<K, V>,
153 MapItemsIterator<K, const V, typename QMap<K, V>::iterator>
154 >{map};
155 }
156
157 template<typename T, typename IdentifierType>
158 struct TypeValue
159 {
160 T value;
161 bool operator==(TypeValue<T, IdentifierType> other) const
162 {
163 return value == other.value;
164 }
165 bool operator!=(TypeValue<T, IdentifierType> other) const
166 {
167 return value != other.value;
168 }
169 bool operator<(TypeValue<T, IdentifierType> other) const
170 {
171 return value < other.value;
172 }
173 bool operator>(TypeValue<T, IdentifierType> other) const
174 {
175 return value > other.value;
176 }
177 bool operator<=(TypeValue<T, IdentifierType> other) const
178 {
179 return value <= other.value;
180 }
181 bool operator>=(TypeValue<T, IdentifierType> other) const
182 {
183 return value >= other.value;
184 }
185 };
186
187 template<typename T, typename R>
188 int qHash(TypeValue<T, R> value)
189 {
190 return qHash(value.value);
191 }
192
193 /**
194 * Iterates a @c glm::mat
195 */
196 template<int X, int Y, typename T, glm::qualifier Q, typename Fn>
197 void iter_matrix(const glm::mat<X, Y, T, Q>& matrix, Fn&& fn)
198 {
199 for (int i = 0; i < X; ++i)
200 {
201 for (int j = 0; j < Y; ++j)
202 {
203 fn(i, j, matrix[i][j]);
204 }
205 }
206 }
207
208 inline QDataStream& operator<<(QDataStream& stream, const glm::vec3& vec)
209 {
210 return stream << vec.x << vec.y << vec.z;
211 }
212
213 inline QDataStream& operator>>(QDataStream& stream, glm::vec3& vec)
214 {
215 return stream >> vec.x >> vec.y >> vec.z;
216 }
217
218 template<int X, int Y, typename T, glm::qualifier Q>
219 QDataStream& operator<<(QDataStream& stream, const glm::mat<X, Y, T, Q>& mat)
220 {
221 iter_matrix(mat, [&stream](int, int, float x)
222 {
223 stream << x;
224 });
225 return stream;
226 }
227
228 template<int X, int Y, typename T, glm::qualifier Q>
229 QDataStream& operator>>(QDataStream& stream, glm::mat<X, Y, T, Q>& mat)
230 {
231 iter_matrix(mat, [&stream](int, int, float x)
232 {
233 stream >> x;
234 });
235 return stream;
236 }
237
238 template<std::size_t N, typename T>
239 std::array<T, N> vectorToArray(const std::vector<T>& x)
240 {
241 std::array<T, N> result;
242 for (std::size_t i = 0; i < x.size() and i < N; i += 1)
243 {
244 result[i] = x[i];
245 }
246 return result;
247 }
248
249 template<typename T>
250 std::optional<T> pointerToOptional(const T* p)
251 {
252 std::optional<T> result;
253 if (p != nullptr) {
254 result = *p;
255 }
256 return result;
257 }
258
259 template<typename T, typename R>
260 void removeFromMap(std::map<T, R>& map, T&& key)
261 {
262 const auto it = map.find(key);
263 if (it != map.end()) {
264 map.erase(it);
265 }
266 }
267
268 template<typename T>
269 using opt = std::optional<T>;
270
271 // some magic code from https://en.cppreference.com/w/cpp/utility/variant/visit
272 // for use with std::visit
273 template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
274 template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

mercurial