src/model.h

changeset 211
b27b90fb993f
parent 210
232e7634cc8a
child 212
27259810da6d
equal deleted inserted replaced
210:232e7634cc8a 211:b27b90fb993f
58 { 58 {
59 using type = std::remove_reference_t<R>&; 59 using type = std::remove_reference_t<R>&;
60 }; 60 };
61 61
62 template<typename T, typename R> 62 template<typename T, typename R>
63 struct transfer_reference<const T&, R>
64 {
65 using type = const std::remove_reference_t<R>&;
66 };
67
68 template<typename T, typename R>
63 struct transfer_reference<T&&, R> 69 struct transfer_reference<T&&, R>
64 { 70 {
65 using type = std::remove_reference_t<R>&&; 71 using type = std::remove_reference_t<R>&&;
66 }; 72 };
67 73
86 Triangle, 92 Triangle,
87 Quadrilateral, 93 Quadrilateral,
88 ConditionalEdge>>; 94 ConditionalEdge>>;
89 95
90 template<typename T> 96 template<typename T>
91 struct remove_color { using type = T; }; 97 struct remove_color {};
92 98
93 template<typename T> 99 template<typename T>
94 struct remove_color<Colored<T>> { using type = T; }; 100 struct remove_color<Colored<T>> { using type = T; };
95 101
96 template<typename T> 102 template<typename T>
97 struct remove_color<Colored<T>&> { using type = T&; }; 103 struct remove_color<Colored<T>&> { using type = T&; };
98 104
99 template<typename T> 105 template<typename T>
106 struct remove_color<const Colored<T>&> { using type = const T&; };
107
108 template<typename T>
100 struct remove_color<Colored<T>&&> { using type = T&&; }; 109 struct remove_color<Colored<T>&&> { using type = T&&; };
101 110
102 template<typename T> 111 template<typename T>
103 using remove_color_t = typename remove_color<T>::type; 112 using remove_color_t = typename remove_color<T>::type;
104 113
114 static_assert(std::is_same_v<remove_color_t<Colored<Triangle>>, Triangle>);
115 static_assert(std::is_same_v<remove_color_t<Colored<Triangle>&>, Triangle&>);
116 static_assert(std::is_same_v<remove_color_t<const Colored<Triangle>&>, const Triangle&>);
117
105 template<typename T> 118 template<typename T>
106 constexpr remove_color_t<T&&> extract_colored(T&& x) 119 constexpr remove_color_t<T&&> extract_colored(T&& x)
107 { 120 {
108 return static_cast<remove_color_t<T&&>>(x); 121 return static_cast<remove_color_t<T&&>>(x);
109 } 122 }
110 123
111 template<typename Ret, typename T> 124 template<typename Ret, typename Fn1, typename Fn2, typename Fn3, typename Fn4, typename T>
112 constexpr auto visitPolygon( 125 constexpr auto visitPolygon(Fn1&& f1, Fn2&& f2, Fn3&& f3, Fn4&& f4, T&& element)
113 std::function<Ret(transfer_reference_t<T&&, LineSegment>)> f1, 126 {
114 std::function<Ret(transfer_reference_t<T&&, Triangle>)> f2, 127 if (std::holds_alternative<LineSegment>(element)) {
115 std::function<Ret(transfer_reference_t<T&&, Quadrilateral>)> f3, 128 return f1(std::get<LineSegment>(element));
116 std::function<Ret(transfer_reference_t<T&&, ConditionalEdge>)> f4, 129 }
117 T&& element) 130 else if (std::holds_alternative<Triangle>(element)) {
118 { 131 return f2(std::get<Triangle>(element));
119 return std::visit(overloaded{f1, f2, f3, f4}, extract_colored(element)); 132 }
133 else if (std::holds_alternative<Quadrilateral>(element)) {
134 return f3(std::get<Quadrilateral>(element));
135 }
136 else {
137 return f4(std::get<ConditionalEdge>(element));
138 }
120 } 139 }
121 140
122 template<typename T, typename Fn> 141 template<typename T, typename Fn>
123 constexpr void visitPoints(T&& element, Fn func) 142 constexpr void visitPoints(Fn&& func, T&& element)
124 { 143 {
125 visitPolygon<void>( 144 visitPolygon<void>(
126 [&func](transfer_reference_t<T&&, LineSegment> edge) 145 [&func](transfer_reference_t<T&&, LineSegment> edge)
127 { 146 {
128 func(edge.p1); 147 func(edge.p1);

mercurial