33 constexpr char mainwindow[] = "mainwindow"; |
33 constexpr char mainwindow[] = "mainwindow"; |
34 } |
34 } |
35 |
35 |
36 namespace ldraw |
36 namespace ldraw |
37 { |
37 { |
|
38 class Object; |
|
39 |
38 // Uniquely identifies a model body object |
40 // Uniquely identifies a model body object |
|
41 template<typename T> |
39 struct Id |
42 struct Id |
40 { |
43 { |
41 std::int32_t value; |
44 std::int32_t value; |
42 constexpr bool operator<(ldraw::Id other) const |
45 template<typename A, typename B> |
|
46 static constexpr bool is_base_or_base_of = std::disjunction_v<std::is_base_of<A, B>, std::is_base_of<B, A>>; |
|
47 template<typename R, typename = std::enable_if_t<is_base_or_base_of<T, R>>> |
|
48 constexpr bool operator<(ldraw::Id<R> other) const |
43 { |
49 { |
44 return this->value < other.value; |
50 return this->value < other.value; |
45 } |
51 } |
46 friend constexpr unsigned int qHash(ldraw::Id id) |
52 friend constexpr unsigned int qHash(ldraw::Id<T> id) |
47 { |
53 { |
48 return qHash(id.value); |
54 return qHash(id.value); |
49 } |
55 } |
50 friend bool operator==(ldraw::Id one, ldraw::Id other) |
56 // Allow comparing ids as long as they are related |
|
57 template<typename R, typename = std::enable_if_t<is_base_or_base_of<T, R>>> |
|
58 friend bool operator==(ldraw::Id<T> one, ldraw::Id<R> other) |
51 { |
59 { |
52 return one.value == other.value; |
60 return one.value == other.value; |
53 } |
61 } |
|
62 // Allow upcasting |
|
63 template<typename R, typename = std::enable_if_t<std::is_base_of_v<R, T>>> |
|
64 constexpr operator Id<R>() const |
|
65 { |
|
66 return Id<R>{this->value}; |
|
67 } |
54 }; |
68 }; |
55 using id_t = Id; |
69 |
56 constexpr id_t NULL_ID = id_t{0}; |
70 using id_t = Id<Object>; |
|
71 using triangleid_t = Id<class Triangle>; |
|
72 using quadrilateralid_t = Id<class Quadrilateral>; |
|
73 using edgeid_t = Id<class EdgeLine>; |
|
74 using conditionaledgeid_t = Id<class ConditionalEdge>; |
|
75 using subfileid_t = Id<class SubfileReference>; |
|
76 |
|
77 constexpr struct |
|
78 { |
|
79 template<typename T> |
|
80 constexpr operator Id<T>() const |
|
81 { |
|
82 return Id<T>{0}; |
|
83 } |
|
84 } NULL_ID = {}; |
|
85 |
|
86 template<typename T> |
|
87 inline bool operator==(Id<T> one, decltype(NULL_ID)) |
|
88 { |
|
89 return one.value == 0; |
|
90 } |
|
91 |
|
92 template<typename T> |
|
93 inline bool operator<(Id<T> one, decltype(NULL_ID)) |
|
94 { |
|
95 return one.value < 0; |
|
96 } |
57 } |
97 } |
58 |
98 |
59 constexpr std::size_t operator""_z(const unsigned long long int x) |
99 constexpr std::size_t operator""_z(const unsigned long long int x) |
60 { |
100 { |
61 return static_cast<std::size_t>(x); |
101 return static_cast<std::size_t>(x); |