45 QString code; |
45 QString code; |
46 }; |
46 }; |
47 |
47 |
48 struct Empty {}; |
48 struct Empty {}; |
49 |
49 |
|
50 template<typename T, typename R> |
|
51 struct transfer_reference |
|
52 { |
|
53 using type = std::remove_reference_t<R>; |
|
54 }; |
|
55 |
|
56 template<typename T, typename R> |
|
57 struct transfer_reference<T&, R> |
|
58 { |
|
59 using type = std::remove_reference_t<R>&; |
|
60 }; |
|
61 |
|
62 template<typename T, typename R> |
|
63 struct transfer_reference<T&&, R> |
|
64 { |
|
65 using type = std::remove_reference_t<R>&&; |
|
66 }; |
|
67 |
|
68 template<typename T, typename R> |
|
69 using transfer_reference_t = typename transfer_reference<T, R>::type; |
|
70 static_assert(std::is_same_v<transfer_reference_t<int, char>, char>); |
|
71 static_assert(std::is_same_v<transfer_reference_t<int&, char>, char&>); |
|
72 static_assert(std::is_same_v<transfer_reference_t<int&&, char>, char&&>); |
|
73 |
50 using ModelElement = std::variant< |
74 using ModelElement = std::variant< |
51 Colored<SubfileReference>, |
75 Colored<SubfileReference>, |
52 Colored<LineSegment>, |
76 Colored<LineSegment>, |
53 Colored<Triangle>, |
77 Colored<Triangle>, |
54 Colored<Quadrilateral>, |
78 Colored<Quadrilateral>, |
55 Colored<ConditionalEdge>, |
79 Colored<ConditionalEdge>, |
56 Comment, |
80 Comment, |
57 Empty, |
81 Empty, |
58 ParseError>; |
82 ParseError>; |
|
83 |
|
84 using PolygonElement = Colored<std::variant< |
|
85 LineSegment, |
|
86 Triangle, |
|
87 Quadrilateral, |
|
88 ConditionalEdge>>; |
|
89 |
|
90 template<typename T> |
|
91 struct remove_color { using type = T; }; |
|
92 |
|
93 template<typename T> |
|
94 struct remove_color<Colored<T>> { using type = T; }; |
|
95 |
|
96 template<typename T> |
|
97 struct remove_color<Colored<T>&> { using type = T&; }; |
|
98 |
|
99 template<typename T> |
|
100 struct remove_color<Colored<T>&&> { using type = T&&; }; |
|
101 |
|
102 template<typename T> |
|
103 using remove_color_t = typename remove_color<T>::type; |
|
104 |
|
105 template<typename T> |
|
106 constexpr remove_color_t<T&&> extract_colored(T&& x) |
|
107 { |
|
108 return static_cast<remove_color_t<T&&>>(x); |
|
109 } |
|
110 |
|
111 template<typename Ret, typename T> |
|
112 constexpr auto visitPolygon( |
|
113 std::function<Ret(transfer_reference_t<T&&, LineSegment>)> f1, |
|
114 std::function<Ret(transfer_reference_t<T&&, Triangle>)> f2, |
|
115 std::function<Ret(transfer_reference_t<T&&, Quadrilateral>)> f3, |
|
116 std::function<Ret(transfer_reference_t<T&&, ConditionalEdge>)> f4, |
|
117 T&& element) |
|
118 { |
|
119 return std::visit(overloaded{f1, f2, f3, f4}, extract_colored(element)); |
|
120 } |
|
121 |
|
122 template<typename T, typename Fn> |
|
123 constexpr void visitPoints(T&& element, Fn func) |
|
124 { |
|
125 visitPolygon<void>( |
|
126 [&func](transfer_reference_t<T&&, LineSegment> edge) |
|
127 { |
|
128 func(edge.p1); |
|
129 func(edge.p2); |
|
130 }, |
|
131 [&func](transfer_reference_t<T&&, Triangle>& tri) |
|
132 { |
|
133 func(tri.p1); |
|
134 func(tri.p2); |
|
135 func(tri.p3); |
|
136 }, |
|
137 [&func](transfer_reference_t<T&&, Quadrilateral>& quad) |
|
138 { |
|
139 func(quad.p1); |
|
140 func(quad.p2); |
|
141 func(quad.p3); |
|
142 func(quad.p4); |
|
143 }, |
|
144 [&func](transfer_reference_t<T&&, ConditionalEdge>& cedge) |
|
145 { |
|
146 func(cedge.p1); |
|
147 func(cedge.p2); |
|
148 func(cedge.c1); |
|
149 func(cedge.c2); |
|
150 }, |
|
151 element); |
|
152 } |
59 |
153 |
60 QString modelElementToString(const ModelElement& element); |
154 QString modelElementToString(const ModelElement& element); |
61 struct ModelId |
155 struct ModelId |
62 { |
156 { |
63 std::int32_t value; |
157 std::int32_t value; |