src/main.h

changeset 200
ca23936b455b
parent 196
6bcb284679d4
child 205
1a4342d80de7
equal deleted inserted replaced
199:6988973515d2 200:ca23936b455b
32 { 32 {
33 // List of setting groups 33 // List of setting groups
34 constexpr char mainwindow[] = "mainwindow"; 34 constexpr char mainwindow[] = "mainwindow";
35 } 35 }
36 36
37 namespace ldraw
38 {
39 class Object;
40
41 // Uniquely identifies a model body object
42 template<typename T>
43 struct Id
44 {
45 std::int32_t value;
46 template<typename A, typename B>
47 static constexpr bool is_base_or_base_of = std::disjunction_v<std::is_base_of<A, B>, std::is_base_of<B, A>>;
48 template<typename R, typename = std::enable_if_t<is_base_or_base_of<T, R>>>
49 constexpr bool operator<(ldraw::Id<R> other) const
50 {
51 return this->value < other.value;
52 }
53 friend constexpr unsigned int qHash(ldraw::Id<T> id)
54 {
55 return qHash(id.value);
56 }
57 // Allow comparing ids as long as they are related
58 template<typename R, typename = std::enable_if_t<is_base_or_base_of<T, R>>>
59 friend bool operator==(ldraw::Id<T> one, ldraw::Id<R> other)
60 {
61 return one.value == other.value;
62 }
63 // Allow upcasting
64 template<typename R, typename = std::enable_if_t<std::is_base_of_v<R, T>>>
65 constexpr operator Id<R>() const
66 {
67 return Id<R>{this->value};
68 }
69 };
70
71 using id_t = Id<Object>;
72 using triangleid_t = Id<class Triangle>;
73 using quadrilateralid_t = Id<class Quadrilateral>;
74 using edgeid_t = Id<class EdgeLine>;
75 using conditionaledgeid_t = Id<class ConditionalEdge>;
76 using subfileid_t = Id<class SubfileReference>;
77 using commentid_t = Id<class Comment>;
78 using metacommandid_t = Id<class MetaCommand>;
79
80 constexpr struct NullId
81 {
82 template<typename T>
83 constexpr operator Id<T>() const
84 {
85 return Id<T>{0};
86 }
87 static constexpr decltype(ldraw::id_t::value) value = 0;
88 } NULL_ID = {};
89
90 template<typename T>
91 inline bool operator==(Id<T> one, decltype(NULL_ID))
92 {
93 return one.value == 0;
94 }
95
96 template<typename T>
97 inline bool operator!=(Id<T> one, decltype(NULL_ID))
98 {
99 return one.value != 0;
100 }
101
102 template<typename T>
103 inline bool operator<(Id<T> one, decltype(NULL_ID))
104 {
105 return one.value < 0;
106 }
107 }
108
109 constexpr std::size_t operator""_z(const unsigned long long int x) 37 constexpr std::size_t operator""_z(const unsigned long long int x)
110 { 38 {
111 return static_cast<std::size_t>(x); 39 return static_cast<std::size_t>(x);
112 } 40 }
113 41
260 int qHash(TypeValue<T, R> value) 188 int qHash(TypeValue<T, R> value)
261 { 189 {
262 return qHash(value.value); 190 return qHash(value.value);
263 } 191 }
264 192
265 using ModelId = TypeValue<int, struct TypeValueModelId>;
266
267 /** 193 /**
268 * Iterates a @c glm::mat 194 * Iterates a @c glm::mat
269 */ 195 */
270 template<int X, int Y, typename T, glm::qualifier Q, typename Fn> 196 template<int X, int Y, typename T, glm::qualifier Q, typename Fn>
271 void iter_matrix(const glm::mat<X, Y, T, Q>& matrix, Fn&& fn) 197 void iter_matrix(const glm::mat<X, Y, T, Q>& matrix, Fn&& fn)
277 fn(i, j, matrix[i][j]); 203 fn(i, j, matrix[i][j]);
278 } 204 }
279 } 205 }
280 } 206 }
281 207
282 QDataStream& operator<<(QDataStream&, const glm::vec3&); 208 inline QDataStream& operator<<(QDataStream& stream, const glm::vec3& vec)
283 QDataStream& operator>>(QDataStream&, glm::vec3&); 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 }
284 217
285 template<int X, int Y, typename T, glm::qualifier Q> 218 template<int X, int Y, typename T, glm::qualifier Q>
286 QDataStream& operator<<(QDataStream& stream, const glm::mat<X, Y, T, Q>& mat) 219 QDataStream& operator<<(QDataStream& stream, const glm::mat<X, Y, T, Q>& mat)
287 { 220 {
288 iter_matrix(mat, [&stream](int, int, float x) 221 iter_matrix(mat, [&stream](int, int, float x)
310 { 243 {
311 result[i] = x[i]; 244 result[i] = x[i];
312 } 245 }
313 return result; 246 return result;
314 } 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 // some magic code from https://en.cppreference.com/w/cpp/utility/variant/visit
269 // for use with std::visit
270 template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
271 template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

mercurial