src/model.h

changeset 211
b27b90fb993f
parent 210
232e7634cc8a
child 212
27259810da6d
--- a/src/model.h	Thu Jun 09 13:32:55 2022 +0300
+++ b/src/model.h	Thu Jun 09 19:11:27 2022 +0300
@@ -60,6 +60,12 @@
 };
 
 template<typename T, typename R>
+struct transfer_reference<const T&, R>
+{
+	using type = const std::remove_reference_t<R>&;
+};
+
+template<typename T, typename R>
 struct transfer_reference<T&&, R>
 {
 	using type = std::remove_reference_t<R>&&;
@@ -88,7 +94,7 @@
 	ConditionalEdge>>;
 
 template<typename T>
-struct remove_color { using type = T; };
+struct remove_color {};
 
 template<typename T>
 struct remove_color<Colored<T>> { using type = T; };
@@ -97,30 +103,43 @@
 struct remove_color<Colored<T>&> { using type = T&; };
 
 template<typename T>
+struct remove_color<const Colored<T>&> { using type = const T&; };
+
+template<typename T>
 struct remove_color<Colored<T>&&> { using type = T&&; };
 
 template<typename T>
 using remove_color_t = typename remove_color<T>::type;
 
+static_assert(std::is_same_v<remove_color_t<Colored<Triangle>>, Triangle>);
+static_assert(std::is_same_v<remove_color_t<Colored<Triangle>&>, Triangle&>);
+static_assert(std::is_same_v<remove_color_t<const Colored<Triangle>&>, const Triangle&>);
+
 template<typename T>
 constexpr remove_color_t<T&&> extract_colored(T&& x)
 {
 	return static_cast<remove_color_t<T&&>>(x);
 }
 
-template<typename Ret, typename T>
-constexpr auto visitPolygon(
-	std::function<Ret(transfer_reference_t<T&&, LineSegment>)> f1,
-	std::function<Ret(transfer_reference_t<T&&, Triangle>)> f2,
-	std::function<Ret(transfer_reference_t<T&&, Quadrilateral>)> f3,
-	std::function<Ret(transfer_reference_t<T&&, ConditionalEdge>)> f4,
-	T&& element)
+template<typename Ret, typename Fn1, typename Fn2, typename Fn3, typename Fn4, typename T>
+constexpr auto visitPolygon(Fn1&& f1, Fn2&& f2, Fn3&& f3, Fn4&& f4, T&& element)
 {
-	return std::visit(overloaded{f1, f2, f3, f4}, extract_colored(element));
+	if (std::holds_alternative<LineSegment>(element)) {
+		return f1(std::get<LineSegment>(element));
+	}
+	else if (std::holds_alternative<Triangle>(element)) {
+		return f2(std::get<Triangle>(element));
+	}
+	else if (std::holds_alternative<Quadrilateral>(element)) {
+		return f3(std::get<Quadrilateral>(element));
+	}
+	else {
+		return f4(std::get<ConditionalEdge>(element));
+	}
 }
 
 template<typename T, typename Fn>
-constexpr void visitPoints(T&& element, Fn func)
+constexpr void visitPoints(Fn&& func, T&& element)
 {
 	visitPolygon<void>(
 		[&func](transfer_reference_t<T&&, LineSegment> edge)

mercurial