From 841cf8dca8de452c55a34c60df3fbd3308ee47e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 14 Oct 2021 10:57:05 +0200 Subject: [PATCH 01/14] avoid duplicating code by sorting points --- .../Intersections_2/Segment_2_Segment_2.h | 218 ++++-------------- 1 file changed, 48 insertions(+), 170 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index 3b9e7003a40..41314346379 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -85,187 +85,65 @@ do_intersect(const typename K::Segment_2 &seg1, const typename K::Segment_2 &seg2, const K& k) { - typename K::Point_2 const & A1 = seg1.source(); - typename K::Point_2 const & A2 = seg1.target(); - typename K::Point_2 const & B1 = seg2.source(); - typename K::Point_2 const & B2 = seg2.target(); typename K::Less_xy_2 less_xy; + + bool seg1_is_left_to_right = less_xy(seg1.source(),seg1.target()); + bool seg2_is_left_to_right = less_xy(seg2.source(),seg2.target()); + + int A1_id = seg1_is_left_to_right ? 0 : 1; + int A2_id = seg1_is_left_to_right ? 1 : 0; + int B1_id = seg2_is_left_to_right ? 0 : 1; + int B2_id = seg2_is_left_to_right ? 1 : 0; + + typename K::Point_2 const & A1 = seg1.point(A1_id); + typename K::Point_2 const & A2 = seg1.point(A2_id); + typename K::Point_2 const & B1 = seg2.point(B1_id); + typename K::Point_2 const & B2 = seg2.point(B2_id); + typename K::Compare_xy_2 compare_xy; - if (less_xy(A1,A2)) { - if (less_xy(B1,B2)) { - if (less_xy(A2,B1) - || less_xy(B2,A1)) - return false; - } else { - if (less_xy(A2,B2) - || less_xy(B1,A1)) - return false; - } - } else { - if (less_xy(B1,B2)) { - if (less_xy(A1,B1) - || less_xy(B2,A2)) - return false; - } else { - if (less_xy(A1,B2) - || less_xy(B1,A2)) - return false; - } - } - if (less_xy(A1,A2)) { - if (less_xy(B1,B2)) { - switch(make_certain(compare_xy(A1,B1))) { - case SMALLER: - switch(make_certain(compare_xy(A2,B1))) { - case SMALLER: - return false; - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(A2,B2))) { - case SMALLER: - return seg_seg_do_intersect_crossing(A1,A2,B1,B2, k); - case EQUAL: - return true; - default: // LARGER - return seg_seg_do_intersect_contained(A1,A2,B1,B2, k); - } - } - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(B2,A1))) { - case SMALLER: - return false; - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(B2,A2))) { - case SMALLER: - return seg_seg_do_intersect_crossing(B1,B2,A1,A2, k); - case EQUAL: - return true; - default: // LARGER - return seg_seg_do_intersect_contained(B1,B2,A1,A2, k); - } - } - } - } else { - switch(make_certain(compare_xy(A1,B2))) { - case SMALLER: - switch(make_certain(compare_xy(A2,B2))) { - case SMALLER: - return false; - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(A2,B1))) { - case SMALLER: - return seg_seg_do_intersect_crossing(A1,A2,B2,B1, k); - case EQUAL: - return true; - default: // LARGER - return seg_seg_do_intersect_contained(A1,A2,B2,B1, k); - } - } - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(B1,A1))) { - case SMALLER: - return false; - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(B1,A2))) { - case SMALLER: - return seg_seg_do_intersect_crossing(B2,B1,A1,A2, k); - case EQUAL: - return true; - default: // LARGER - return seg_seg_do_intersect_contained(B2,B1,A1,A2, k); - } - } - } - } - } else { - if (less_xy(B1,B2)) { - switch(make_certain(compare_xy(A2,B1))) { - case SMALLER: - switch(make_certain(compare_xy(A1,B1))) { - case SMALLER: - return false; - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(A1,B2))) { - case SMALLER: - return seg_seg_do_intersect_crossing(A2,A1,B1,B2, k); - case EQUAL: - return true; - default: // LARGER - return seg_seg_do_intersect_contained(A2,A1,B1,B2, k); - } - } - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(B2,A2))) { - case SMALLER: - return false; - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(B2,A1))) { - case SMALLER: - return seg_seg_do_intersect_crossing(B1,B2,A2,A1, k); - case EQUAL: - return true; - default: // LARGER - return seg_seg_do_intersect_contained(B1,B2,A2,A1, k); - } - } - } - } else { + // first try to filter using the bbox of the segments + if (less_xy(A2,B1) + || less_xy(B2,A1)) + return false; + + switch(make_certain(compare_xy(A1,B1))) { + case SMALLER: + switch(make_certain(compare_xy(A2,B1))) { + case SMALLER: + return false; + case EQUAL: + return true; + default: // LARGER switch(make_certain(compare_xy(A2,B2))) { case SMALLER: - switch(make_certain(compare_xy(A1,B2))) { - case SMALLER: - return false; - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(A1,B1))) { - case SMALLER: - return seg_seg_do_intersect_crossing(A2,A1,B2,B1, k); - case EQUAL: - return true; - default: // LARGER - return seg_seg_do_intersect_contained(A2,A1,B2,B1, k); - } - } + return seg_seg_do_intersect_crossing(A1,A2,B1,B2, k); case EQUAL: return true; default: // LARGER - switch(make_certain(compare_xy(B1,A2))) { - case SMALLER: - return false; - case EQUAL: - return true; - default: // LARGER - switch(make_certain(compare_xy(B1,A1))) { - case SMALLER: - return seg_seg_do_intersect_crossing(B2,B1,A2,A1, k); - case EQUAL: - return true; - default: // LARGER - return seg_seg_do_intersect_contained(B2,B1,A2,A1, k); - } - } + return seg_seg_do_intersect_contained(A1,A2,B1,B2, k); + } + } + case EQUAL: + return true; + default: // LARGER + switch(make_certain(compare_xy(B2,A1))) { + case SMALLER: + return false; + case EQUAL: + return true; + default: // LARGER + switch(make_certain(compare_xy(B2,A2))) { + case SMALLER: + return seg_seg_do_intersect_crossing(B1,B2,A1,A2, k); + case EQUAL: + return true; + default: // LARGER + return seg_seg_do_intersect_contained(B1,B2,A1,A2, k); } } } + CGAL_kernel_assertion(false); return false; } From aa1b53a4a158bb5d9b0fbf105afad4cedfcfb8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 14 Oct 2021 10:57:39 +0200 Subject: [PATCH 02/14] add more tests --- .../Intersections_2/test_intersections_2.cpp | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index 9cde3a3f12e..1d0f89180e1 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -431,6 +431,56 @@ struct Test check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 0), p( 8, 0)), S(P( 1, 0), P( 8, 0))); check_intersection (S(p(68, 106), p(192, 106)), S(p(150, 106), p(255, 106)), S(P(150, 106), P(192, 106))); check_intersection (S(p( 1, 10), p( 1, 2)), S(p( 1, 7), p( 1, 3)), S(P( 1, 3), P( 1, 7))); + + // exact point intersection + check_intersection (S(p( 3.14, 0), p( 3.14, 10)), S(p( 3.14, 3.456), p( 5, 10)), p( 3.14, 3.456)); + check_intersection (S(p( 3.14, 0), p( 3.14, 10)), S(p( 5, 10), p( 3.14, 3.456)), p( 3.14, 3.456)); + check_intersection (S(p( 3.14, 0), p( 3.14, 10)), S(p( 3.14, 3.456), p( -5, 10)), p( 3.14, 3.456)); + check_intersection (S(p( 3.14, 0), p( 3.14, 10)), S(p( -5, 10), p( 3.14, 3.456)), p( 3.14, 3.456)); + check_intersection (S(p( 0, 0), p( 44, 44)), S(p( 44, 44), p( 55, 55)), p( 44, 44)); + check_intersection (S(p( 0, 0), p( 44, 44)), S(p( 55, 55), p( 44, 44)), p( 44, 44)); + check_intersection (S(p( 44, 44), p( 0, 0)), S(p( 44, 44), p( 55, 55)), p( 44, 44)); + check_intersection (S(p( 44, 44), p( 0, 0)), S(p( 55, 55), p( 44, 44)), p( 44, 44)); + check_intersection (S(p( 0, 0), p( -44, -44)), S(p( -44, -44), p( -55, -55)), p( -44, -44)); + check_intersection (S(p( 0, 0), p( -44, -44)), S(p( -55, -55), p( -44, -44)), p( -44, -44)); + check_intersection (S(p( -44, -44), p( 0, 0)), S(p( -44, -44), p( -55, -55)), p( -44, -44)); + check_intersection (S(p( -44, -44), p( 0, 0)), S(p( -55, -55), p( -44, -44)), p( -44, -44)); + + // more segment intersection (containment) + check_intersection (S(p(0,0), p(4,4)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2))); + check_intersection (S(p(0,0), p(4,4)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2))); + check_intersection (S(p(4,4), p(0,0)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2))); + check_intersection (S(p(4,4), p(0,0)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2))); + + // more segment intersection (overlap) + check_intersection (S(p( 0,0), p( 2,2)), S(p(1,1), p(4,4)), S(p(1,1), p(2,2))); + check_intersection (S(p( 0,0), p( 2,2)), S(p(4,4), p(1,1)), S(p(1,1), p(2,2))); + check_intersection (S(p( 2,2), p( 0,0)), S(p(1,1), p(4,4)), S(p(1,1), p(2,2))); + check_intersection (S(p( 2,2), p( 0,0)), S(p(4,4), p(1,1)), S(p(1,1), p(2,2))); + check_intersection (S(p( 0,0), p( -2,-2)), S(p(-1,-1), p(-4,-4)), S(p(-2,-2),p(-1,-1))); + check_intersection (S(p( 0,0), p( -2,-2)), S(p(-4,-4), p(-1,-1)), S(p(-2,-2),p(-1,-1))); + check_intersection (S(p( -2,-2), p( 0,0)), S(p(-1,-1), p(-4,-4)), S(p(-2,-2),p(-1,-1))); + check_intersection (S(p( -2,-2), p( 0,0)), S(p(-4,-4), p(-1,-1)), S(p(-2,-2),p(-1,-1))); + + // more segment intersection (one common point) + check_intersection (S(p( 0,0), p( 2,2)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2))); + check_intersection (S(p( 0,0), p( 2,2)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2))); + check_intersection (S(p( 2,2), p( 0,0)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2))); + check_intersection (S(p( 2,2), p( 0,0)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2))); + check_intersection (S(p( 0,0), p( -2,-2)), S(p(-1,-1), p(-2,-2)), S(p(-2,-2),p(-1,-1))); + check_intersection (S(p( 0,0), p( -2,-2)), S(p(-2,-2), p(-1,-1)), S(p(-2,-2),p(-1,-1))); + check_intersection (S(p( -2,-2), p( 0,0)), S(p(-1,-1), p(-2,-2)), S(p(-2,-2),p(-1,-1))); + check_intersection (S(p( -2,-2), p( 0,0)), S(p(-2,-2), p(-1,-1)), S(p(-2,-2),p(-1,-1))); + + // more segment intersection (two identical points) + check_intersection (S(p( 1,1), p( 2,2)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2))); + check_intersection (S(p( 1,1), p( 2,2)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2))); + check_intersection (S(p( 2,2), p( 1,1)), S(p(1,1), p(2,2)), S(p(1,1), p(2,2))); + check_intersection (S(p( 2,2), p( 1,1)), S(p(2,2), p(1,1)), S(p(1,1), p(2,2))); + check_intersection (S(p( -1,-1), p( -2,-2)), S(p(-1,-1), p(-2,-2)), S(p(-2,-2),p(-1,-1))); + check_intersection (S(p( -1,-1), p( -2,-2)), S(p(-2,-2), p(-1,-1)), S(p(-2,-2),p(-1,-1))); + check_intersection (S(p( -2,-2), p( -1,-1)), S(p(-1,-1), p(-2,-2)), S(p(-2,-2),p(-1,-1))); + check_intersection (S(p( -2,-2), p( -1,-1)), S(p(-2,-2), p(-1,-1)), S(p(-2,-2),p(-1,-1))); } void R_R() From e19ddaceb494acb87e5afe0d0688c32c13a2b284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 14 Oct 2021 10:58:19 +0200 Subject: [PATCH 03/14] introducing intersection info for segment_2-segment_2 Intersect_2 uses combinarics information from Do_intersect_2 --- .../Intersections_2/Segment_2_Segment_2.h | 237 ++++++++++++++---- 1 file changed, 189 insertions(+), 48 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index 41314346379..27e6f66a407 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -28,62 +28,137 @@ #include #include +#include + namespace CGAL { namespace Intersections { namespace internal { +struct S2S2_inter_info +{ + bool inter = false; + bool dim = 0; + std::array pt_ids = {-1,-1}; + + S2S2_inter_info(bool inter) + : inter(inter) + {} + + S2S2_inter_info(int id) + : inter(true) + { + pt_ids[0]=id; + } + + S2S2_inter_info(int id1,int id2, int dim) + : inter(true) + , dim(dim) + { + pt_ids[0]=id1; + pt_ids[1]=id2; + } +}; + template -inline bool +inline S2S2_inter_info do_intersect(const typename K::Segment_2 &seg1, const typename K::Segment_2 &seg2); - - +// lexicographic order of points p1 < p3 < p2 < p4, with segments (p1,p2) and (p3,p4) template -bool seg_seg_do_intersect_crossing( - const typename K::Point_2 &p1, const typename K::Point_2 &p2, - const typename K::Point_2 &p3, const typename K::Point_2 &p4, - const K& k) +S2S2_inter_info +seg_seg_do_intersect_crossing( + const typename K::Point_2& p1, const typename K::Point_2& p2, + const typename K::Point_2& p3, const typename K::Point_2& p4, + int i1, int i2, int i3, int i4, + const K& k, bool extra_test) { switch (make_certain(k.orientation_2_object()(p1,p2,p3))) { case LEFT_TURN: - return ! (k.orientation_2_object()(p3,p4,p2) == RIGHT_TURN); // right_turn(p3,p4,p2); + { + switch (k.orientation_2_object()(p3,p4,p2)) + { + case COLLINEAR: + return S2S2_inter_info(i2); + case RIGHT_TURN: + return S2S2_inter_info(false); + case LEFT_TURN: + return S2S2_inter_info(true); + } + } case RIGHT_TURN: - return ! (k.orientation_2_object()(p3,p4,p2) == LEFT_TURN); //left_turn(p3,p4,p2); + { + switch (k.orientation_2_object()(p3,p4,p2)) + { + case COLLINEAR: + return S2S2_inter_info(i2); + case RIGHT_TURN: + return S2S2_inter_info(true); + case LEFT_TURN: + return S2S2_inter_info(false); + } + } case COLLINEAR: - return true; + if (extra_test && k.collinear_2_object()(p3,p4,p2)) + return S2S2_inter_info(i3, i2, 1); + return S2S2_inter_info(i3); } CGAL_kernel_assertion(false); - return false; + return S2S2_inter_info(false); +} + + +// lexicographic order of points p1 < p3 < p4 < p2, with segments (p1,p2) and (p3,p4) +template +S2S2_inter_info +seg_seg_do_intersect_contained( + const typename K::Point_2& p1, const typename K::Point_2& p2, + const typename K::Point_2& p3, const typename K::Point_2& p4, + int i1, int i2, int i3, int i4, + const K& k, bool extra_test) +{ + switch (make_certain(k.orientation_2_object()(p1,p2,p3))) { + case LEFT_TURN: + { + switch (k.orientation_2_object()(p1,p2,p4)) + { + case COLLINEAR: + return S2S2_inter_info(i4); + case RIGHT_TURN: + return S2S2_inter_info(true); + case LEFT_TURN: + return S2S2_inter_info(false); + } + } + case RIGHT_TURN: + { + switch (k.orientation_2_object()(p1,p2,p4)) + { + case COLLINEAR: + return S2S2_inter_info(i4); + case RIGHT_TURN: + return S2S2_inter_info(false); + case LEFT_TURN: + return S2S2_inter_info(true); + } + } + case COLLINEAR: + if (extra_test && k.collinear_2_object()(p3,p4,p2)) + return S2S2_inter_info(i3, i4, 1); + return S2S2_inter_info(i3); + } + CGAL_kernel_assertion(false); + return S2S2_inter_info(false); } template -bool seg_seg_do_intersect_contained( - const typename K::Point_2 &p1, const typename K::Point_2 &p2, - const typename K::Point_2 &p3, const typename K::Point_2 &p4, - const K& k) -{ - switch (make_certain(k.orientation_2_object()(p1,p2,p3))) { - case LEFT_TURN: - return ! (k.orientation_2_object()(p1,p2,p4) == LEFT_TURN); // left_turn(p1,p2,p4); - case RIGHT_TURN: - return ! (k.orientation_2_object()(p1,p2,p4) == RIGHT_TURN); // right_turn(p1,p2,p4); - case COLLINEAR: - return true; - } - CGAL_kernel_assertion(false); - return false; -} - - -template -bool -do_intersect(const typename K::Segment_2 &seg1, - const typename K::Segment_2 &seg2, - const K& k) +S2S2_inter_info +do_intersect_with_info(const typename K::Segment_2 &seg1, + const typename K::Segment_2 &seg2, + const K& k, bool extra_test) { typename K::Less_xy_2 less_xy; @@ -105,50 +180,82 @@ do_intersect(const typename K::Segment_2 &seg1, // first try to filter using the bbox of the segments if (less_xy(A2,B1) || less_xy(B2,A1)) - return false; + return S2S2_inter_info(false); switch(make_certain(compare_xy(A1,B1))) { case SMALLER: switch(make_certain(compare_xy(A2,B1))) { case SMALLER: - return false; + return S2S2_inter_info(false); case EQUAL: - return true; + return S2S2_inter_info(A2_id, B1_id+2, 0); default: // LARGER switch(make_certain(compare_xy(A2,B2))) { case SMALLER: - return seg_seg_do_intersect_crossing(A1,A2,B1,B2, k); + return seg_seg_do_intersect_crossing(A1,A2,B1,B2, A1_id,A2_id,B1_id+2,B2_id+2, k, extra_test); case EQUAL: - return true; + // A1 < B1 < B2 = A1 + if (extra_test && k.collinear_2_object()(A1, A2, B1)) + return S2S2_inter_info(B1_id+2, B2_id+2, 1); // TODO: A2==B2 too but bit is not set + return S2S2_inter_info(A2_id, B2_id+2, 0); default: // LARGER - return seg_seg_do_intersect_contained(A1,A2,B1,B2, k); + return seg_seg_do_intersect_contained(A1,A2,B1,B2, A1_id,A2_id,B1_id+2,B2_id+2, k, extra_test); } } case EQUAL: - return true; + if (extra_test) + { + switch(make_certain(compare_xy(A2,B2))) { + case SMALLER: + // A1 = B1 < A2 < B2 + if (k.collinear_2_object()(A1,A2,B2)) + return S2S2_inter_info(A1_id, A2_id, 1); // TODO A1==B1 too but bit is not set + break; + case EQUAL: + // A1 = B1 < A2 = B2 + return S2S2_inter_info(A1_id, A2_id, 1); // TODO A1==B1 and A2==B2 too but bits are not set + default: // LARGER + // A1 = B1 < B2 < A2 + if (k.collinear_2_object()(A1,A2,B2)) + return S2S2_inter_info(B1_id+2, B2_id+2, 1); // TODO A1==B1 too but bit is not set + } + } + return S2S2_inter_info(A1_id, B1_id+2, 0); default: // LARGER switch(make_certain(compare_xy(B2,A1))) { case SMALLER: - return false; + return S2S2_inter_info(false); case EQUAL: - return true; + return S2S2_inter_info(A1_id, B2_id+2, 0); default: // LARGER switch(make_certain(compare_xy(B2,A2))) { case SMALLER: - return seg_seg_do_intersect_crossing(B1,B2,A1,A2, k); + return seg_seg_do_intersect_crossing(B1,B2,A1,A2, B1_id+2,B2_id+2,A1_id,A2_id, k, extra_test); case EQUAL: - return true; + // B1 < A1 < A2 = B2 + if (extra_test && k.collinear_2_object()(B1, A1, B2)) + return S2S2_inter_info(A1_id, A2_id, 1); // TODO A2==B2 too but bit not set + return S2S2_inter_info(A2_id, B2_id+2, 0); default: // LARGER - return seg_seg_do_intersect_contained(B1,B2,A1,A2, k); + return seg_seg_do_intersect_contained(B1,B2,A1,A2, B1_id+2,B2_id+2,A1_id,A2_id, k, extra_test); } } } CGAL_kernel_assertion(false); - return false; + return S2S2_inter_info(false); } +template +bool +do_intersect(const typename K::Segment_2 &seg1, + const typename K::Segment_2 &seg2, + const K& k) +{ + return do_intersect_with_info(seg1, seg2, k, false).inter; +} + template class Segment_2_Segment_2_pair { public: @@ -175,10 +282,44 @@ Segment_2_Segment_2_pair::intersection_type() const typename K::Construct_vector_2 construct_vector; if (_result!=UNKNOWN) return _result; - if (!internal::do_intersect(*_seg1, *_seg2, K())) { + + S2S2_inter_info inter_info = do_intersect_with_info(*_seg1, *_seg2, K(), true); + + if (!inter_info.inter) { _result = NO_INTERSECTION; return _result; } + + // check if intersection is a segment + if (inter_info.dim==1) + { + _result=SEGMENT; + // TODO: avoid reference_wrapper? + std::vector< std::reference_wrapper > pts; + for (int i=0;i<2;++i) + if (inter_info.pt_ids[i]>1) + pts.push_back( std::cref(_seg2->point(inter_info.pt_ids[i]-2)) ); + else + pts.push_back( std::cref(_seg1->point(inter_info.pt_ids[i])) ); + CGAL_assertion(pts.size()==2); + _intersection_point = pts[0]; + _other_point = pts[1]; + return _result; + } + + // check if intersection is an input endpoint + if (inter_info.pt_ids[0]>=0) + { + _result = POINT; + if (inter_info.pt_ids[0]>1) + _intersection_point = _seg2->point(inter_info.pt_ids[0]-2); + else + _intersection_point = _seg1->point(inter_info.pt_ids[0]); + return _result; + } + + // TODO: use closed formula for 2 intersecting segments + typename K::Line_2 const &l1 = _seg1->supporting_line(); typename K::Line_2 const &l2 = _seg2->supporting_line(); Line_2_Line_2_pair linepair(&l1, &l2); From c814d11c8e7e0a84b3feee809dbf97ffce17df21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 14 Oct 2021 13:38:47 +0200 Subject: [PATCH 04/14] use close form for intersection in their interior of non-collinear segments --- .../Intersections_2/Segment_2_Segment_2.h | 112 ++---------------- 1 file changed, 13 insertions(+), 99 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index 27e6f66a407..f4a79ecdd70 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -307,10 +307,12 @@ Segment_2_Segment_2_pair::intersection_type() const return _result; } + // starting from here we know that the intersection is a point + _result = POINT; + // check if intersection is an input endpoint if (inter_info.pt_ids[0]>=0) { - _result = POINT; if (inter_info.pt_ids[0]>1) _intersection_point = _seg2->point(inter_info.pt_ids[0]-2); else @@ -318,105 +320,17 @@ Segment_2_Segment_2_pair::intersection_type() const return _result; } - // TODO: use closed formula for 2 intersecting segments + // segments intersect in their interiors + typename K::FT s1_dx = _seg1->point(0).x() - _seg1->point(1).x(), + s1_dy = _seg1->point(0).y() - _seg1->point(1).y(), + s2_dx = _seg2->point(1).x() - _seg2->point(0).x(), + s2_dy = _seg2->point(1).y() - _seg2->point(0).y(), + lx = _seg2->point(1).x() - _seg1->point(1).x(), + ly = _seg2->point(1).y() - _seg1->point(1).y(); + + typename K::FT alpha = (lx*s2_dy-ly*s2_dx)/(s1_dx*s2_dy-s1_dy*s2_dx); + _intersection_point = K().construct_barycenter_2_object()(_seg1->point(0), alpha, _seg1->point(1)); - typename K::Line_2 const &l1 = _seg1->supporting_line(); - typename K::Line_2 const &l2 = _seg2->supporting_line(); - Line_2_Line_2_pair linepair(&l1, &l2); - switch ( linepair.intersection_type()) { - case Line_2_Line_2_pair::NO_INTERSECTION: - default: - _result = NO_INTERSECTION; - break; - case Line_2_Line_2_pair::POINT: - _intersection_point = linepair.intersection_point(); - _result = POINT; - break; - case Line_2_Line_2_pair::LINE: - { - //typedef typename K::RT RT; - typename K::Point_2 const &start1 = _seg1->source(); - typename K::Point_2 const &end1 = _seg1->target(); - typename K::Point_2 const &start2 = _seg2->source(); - typename K::Point_2 const &end2 = _seg2->target(); - typename K::Vector_2 diff1 = construct_vector(start1, end1); - typename K::Point_2 const *minpt; - typename K::Point_2 const *maxpt; - if (CGAL_NTS abs(diff1.x()) > CGAL_NTS abs(diff1.y())) { - if (start1.x() < end1.x()) { - minpt = &start1; - maxpt = &end1; - } else { - minpt = &end1; - maxpt = &start1; - } - if (start2.x() < end2.x()) { - if (start2.x() > minpt->x()) { - minpt = &start2; - } - if (end2.x() < maxpt->x()) { - maxpt = &end2; - } - } else { - if (end2.x() > minpt->x()) { - minpt = &end2; - } - if (start2.x() < maxpt->x()) { - maxpt = &start2; - } - } - if (maxpt->x() < minpt->x()) { - _result = NO_INTERSECTION; - return _result; - } - if (maxpt->x() == minpt->x()) { - _intersection_point = *minpt; - _result = POINT; - return _result; - } - _intersection_point = *minpt; - _other_point = *maxpt; - _result = SEGMENT; - return _result; - } else { - if (start1.y() < end1.y()) { - minpt = &start1; - maxpt = &end1; - } else { - minpt = &end1; - maxpt = &start1; - } - if (start2.y() < end2.y()) { - if (start2.y() > minpt->y()) { - minpt = &start2; - } - if (end2.y() < maxpt->y()) { - maxpt = &end2; - } - } else { - if (end2.y() > minpt->y()) { - minpt = &end2; - } - if (start2.y() < maxpt->y()) { - maxpt = &start2; - } - } - if (maxpt->y() < minpt->y()) { - _result = NO_INTERSECTION; - return _result; - } - if (maxpt->y() == minpt->y()) { - _intersection_point = *minpt; - _result = POINT; - return _result; - } - _intersection_point = *minpt; - _other_point = *maxpt; - _result = SEGMENT; - return _result; - } - } - } return _result; } From ae04cb8be6d16f89ebd9348aef30c8c045b1fd3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 14 Oct 2021 14:08:21 +0200 Subject: [PATCH 05/14] report only what's needed for Intersect_2 --- .../Intersections_2/Segment_2_Segment_2.h | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index f4a79ecdd70..6503b375ca5 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -36,6 +36,10 @@ namespace Intersections { namespace internal { +// struct used to report the combinaric of the intersection +// of 2 2D segments. +// More information could be gathered if exposed in do_intersect. +// See comments with DI_MORE_INFO_TAG struct S2S2_inter_info { bool inter = false; @@ -46,15 +50,17 @@ struct S2S2_inter_info : inter(inter) {} + // intersection is an input endpoint S2S2_inter_info(int id) : inter(true) { pt_ids[0]=id; } - S2S2_inter_info(int id1,int id2, int dim) + // intersection is a segment + S2S2_inter_info(int id1,int id2) : inter(true) - , dim(dim) + , dim(1) { pt_ids[0]=id1; pt_ids[1]=id2; @@ -102,7 +108,7 @@ seg_seg_do_intersect_crossing( } case COLLINEAR: if (extra_test && k.collinear_2_object()(p3,p4,p2)) - return S2S2_inter_info(i3, i2, 1); + return S2S2_inter_info(i3, i2); return S2S2_inter_info(i3); } CGAL_kernel_assertion(false); @@ -146,7 +152,7 @@ seg_seg_do_intersect_contained( } case COLLINEAR: if (extra_test && k.collinear_2_object()(p3,p4,p2)) - return S2S2_inter_info(i3, i4, 1); + return S2S2_inter_info(i3, i4); return S2S2_inter_info(i3); } CGAL_kernel_assertion(false); @@ -188,7 +194,7 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, case SMALLER: return S2S2_inter_info(false); case EQUAL: - return S2S2_inter_info(A2_id, B1_id+2, 0); + return S2S2_inter_info(A2_id); // DI_MORE_INFO_TAG: A2==B1 but only A2 is reported default: // LARGER switch(make_certain(compare_xy(A2,B2))) { case SMALLER: @@ -196,8 +202,8 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, case EQUAL: // A1 < B1 < B2 = A1 if (extra_test && k.collinear_2_object()(A1, A2, B1)) - return S2S2_inter_info(B1_id+2, B2_id+2, 1); // TODO: A2==B2 too but bit is not set - return S2S2_inter_info(A2_id, B2_id+2, 0); + return S2S2_inter_info(B1_id+2, B2_id+2); // DI_MORE_INFO_TAG: A2==B2 but only B2 is reported + return S2S2_inter_info(A2_id); // DI_MORE_INFO_TAG: A2==B2 but only A2 is reported default: // LARGER return seg_seg_do_intersect_contained(A1,A2,B1,B2, A1_id,A2_id,B1_id+2,B2_id+2, k, extra_test); } @@ -209,24 +215,24 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, case SMALLER: // A1 = B1 < A2 < B2 if (k.collinear_2_object()(A1,A2,B2)) - return S2S2_inter_info(A1_id, A2_id, 1); // TODO A1==B1 too but bit is not set + return S2S2_inter_info(A1_id, A2_id); // DI_MORE_INFO_TAG: A1==B1 but only A1 is reported break; case EQUAL: // A1 = B1 < A2 = B2 - return S2S2_inter_info(A1_id, A2_id, 1); // TODO A1==B1 and A2==B2 too but bits are not set + return S2S2_inter_info(A1_id, A2_id); // DI_MORE_INFO_TAG: A1==B1 and A2==B2 but only A1 and A2 are reported default: // LARGER // A1 = B1 < B2 < A2 if (k.collinear_2_object()(A1,A2,B2)) - return S2S2_inter_info(B1_id+2, B2_id+2, 1); // TODO A1==B1 too but bit is not set + return S2S2_inter_info(B1_id+2, B2_id+2); // DI_MORE_INFO_TAG: A1==B1 but only B1 is reported } } - return S2S2_inter_info(A1_id, B1_id+2, 0); + return S2S2_inter_info(A1_id); // DI_MORE_INFO_TAG: A1==B1 but only A1 is reported default: // LARGER switch(make_certain(compare_xy(B2,A1))) { case SMALLER: return S2S2_inter_info(false); case EQUAL: - return S2S2_inter_info(A1_id, B2_id+2, 0); + return S2S2_inter_info(A1_id); // DI_MORE_INFO_TAG: A1==B2 but only A1 is reported default: // LARGER switch(make_certain(compare_xy(B2,A2))) { case SMALLER: @@ -234,8 +240,8 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, case EQUAL: // B1 < A1 < A2 = B2 if (extra_test && k.collinear_2_object()(B1, A1, B2)) - return S2S2_inter_info(A1_id, A2_id, 1); // TODO A2==B2 too but bit not set - return S2S2_inter_info(A2_id, B2_id+2, 0); + return S2S2_inter_info(A1_id, A2_id); // DI_MORE_INFO_TAG: A2==B2 but only A2 is reported + return S2S2_inter_info(A2_id); // DI_MORE_INFO_TAG: A2==B2 but only A2 is reported default: // LARGER return seg_seg_do_intersect_contained(B1,B2,A1,A2, B1_id+2,B2_id+2,A1_id,A2_id, k, extra_test); } From 8534f4784522f2dd0866ed2cd8ce643ea8c43a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 14 Oct 2021 14:15:48 +0200 Subject: [PATCH 06/14] simplify code --- .../Intersections_2/Segment_2_Segment_2.h | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index 6503b375ca5..3b212871857 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -28,8 +28,6 @@ #include #include -#include - namespace CGAL { namespace Intersections { @@ -300,16 +298,12 @@ Segment_2_Segment_2_pair::intersection_type() const if (inter_info.dim==1) { _result=SEGMENT; - // TODO: avoid reference_wrapper? - std::vector< std::reference_wrapper > pts; - for (int i=0;i<2;++i) - if (inter_info.pt_ids[i]>1) - pts.push_back( std::cref(_seg2->point(inter_info.pt_ids[i]-2)) ); - else - pts.push_back( std::cref(_seg1->point(inter_info.pt_ids[i])) ); - CGAL_assertion(pts.size()==2); - _intersection_point = pts[0]; - _other_point = pts[1]; + _intersection_point = (inter_info.pt_ids[0]>1) + ? _seg2->point(inter_info.pt_ids[0]-2) + : _seg1->point(inter_info.pt_ids[0]); + _other_point = inter_info.pt_ids[1]>1 + ? _seg2->point(inter_info.pt_ids[1]-2) + : _seg1->point(inter_info.pt_ids[1]); return _result; } @@ -319,10 +313,9 @@ Segment_2_Segment_2_pair::intersection_type() const // check if intersection is an input endpoint if (inter_info.pt_ids[0]>=0) { - if (inter_info.pt_ids[0]>1) - _intersection_point = _seg2->point(inter_info.pt_ids[0]-2); - else - _intersection_point = _seg1->point(inter_info.pt_ids[0]); + _intersection_point = (inter_info.pt_ids[0]>1) + ? _seg2->point(inter_info.pt_ids[0]-2) + : _seg1->point(inter_info.pt_ids[0]); return _result; } From 1036f2d908364bb65ec83b5246357bf28ff355e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 22 Oct 2021 17:13:18 +0200 Subject: [PATCH 07/14] remove unused variable --- .../include/CGAL/Intersections_2/Segment_2_Segment_2.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index 3b212871857..d7494b3892d 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -283,7 +283,6 @@ template typename Segment_2_Segment_2_pair::Intersection_results Segment_2_Segment_2_pair::intersection_type() const { - typename K::Construct_vector_2 construct_vector; if (_result!=UNKNOWN) return _result; From 546ab87feb8b172d3552bc1bcd2f4db1db3c554d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 22 Oct 2021 17:28:48 +0200 Subject: [PATCH 08/14] add backward compatibility internal functions --- .../Intersections_2/Segment_2_Segment_2.h | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index d7494b3892d..eeff672e407 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -113,6 +113,17 @@ seg_seg_do_intersect_crossing( return S2S2_inter_info(false); } +// used internally by Arr_segment_traits_2template +template +bool +seg_seg_do_intersect_crossing( + const typename K::Point_2& p1, const typename K::Point_2& p2, + const typename K::Point_2& p3, const typename K::Point_2& p4, + const K& k) +{ + return seg_seg_do_intersect_crossing(p1,p2,p3,p4,0,0,0,0,k,false).inter; +} + // lexicographic order of points p1 < p3 < p4 < p2, with segments (p1,p2) and (p3,p4) template @@ -157,6 +168,16 @@ seg_seg_do_intersect_contained( return S2S2_inter_info(false); } +// used internally by Arr_segment_traits_2 +template +bool +seg_seg_do_intersect_contained( + const typename K::Point_2& p1, const typename K::Point_2& p2, + const typename K::Point_2& p3, const typename K::Point_2& p4, + const K& k) +{ + return seg_seg_do_intersect_contained(p1,p2,p3,p4,0,0,0,0,k,false).inter; +} template S2S2_inter_info From b26a46a852242ba00bddde1b23aadd74d3e53e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 26 Oct 2021 11:15:03 +0200 Subject: [PATCH 09/14] fix warnings --- .../CGAL/Intersections_2/Segment_2_Segment_2.h | 16 ++++++++-------- .../Intersections_2/test_intersections_2.cpp | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index eeff672e407..9d88487598e 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -76,7 +76,7 @@ S2S2_inter_info seg_seg_do_intersect_crossing( const typename K::Point_2& p1, const typename K::Point_2& p2, const typename K::Point_2& p3, const typename K::Point_2& p4, - int i1, int i2, int i3, int i4, + int /* i1 */, int i2, int i3, int /* i4 */, const K& k, bool extra_test) { switch (make_certain(k.orientation_2_object()(p1,p2,p3))) { @@ -88,7 +88,7 @@ seg_seg_do_intersect_crossing( return S2S2_inter_info(i2); case RIGHT_TURN: return S2S2_inter_info(false); - case LEFT_TURN: + default: // LEFT_TURN return S2S2_inter_info(true); } } @@ -100,11 +100,11 @@ seg_seg_do_intersect_crossing( return S2S2_inter_info(i2); case RIGHT_TURN: return S2S2_inter_info(true); - case LEFT_TURN: + default: // LEFT_TURN return S2S2_inter_info(false); } } - case COLLINEAR: + default: //COLLINEAR if (extra_test && k.collinear_2_object()(p3,p4,p2)) return S2S2_inter_info(i3, i2); return S2S2_inter_info(i3); @@ -131,7 +131,7 @@ S2S2_inter_info seg_seg_do_intersect_contained( const typename K::Point_2& p1, const typename K::Point_2& p2, const typename K::Point_2& p3, const typename K::Point_2& p4, - int i1, int i2, int i3, int i4, + int /* i1 */, int /* i2 */, int i3, int i4, const K& k, bool extra_test) { switch (make_certain(k.orientation_2_object()(p1,p2,p3))) { @@ -143,7 +143,7 @@ seg_seg_do_intersect_contained( return S2S2_inter_info(i4); case RIGHT_TURN: return S2S2_inter_info(true); - case LEFT_TURN: + default: // LEFT_TURN return S2S2_inter_info(false); } } @@ -155,11 +155,11 @@ seg_seg_do_intersect_contained( return S2S2_inter_info(i4); case RIGHT_TURN: return S2S2_inter_info(false); - case LEFT_TURN: + default: // LEFT_TURN return S2S2_inter_info(true); } } - case COLLINEAR: + default: // COLLINEAR if (extra_test && k.collinear_2_object()(p3,p4,p2)) return S2S2_inter_info(i3, i4); return S2S2_inter_info(i3); diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index 1d0f89180e1..40c55d26c66 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -433,10 +433,10 @@ struct Test check_intersection (S(p( 1, 10), p( 1, 2)), S(p( 1, 7), p( 1, 3)), S(P( 1, 3), P( 1, 7))); // exact point intersection - check_intersection (S(p( 3.14, 0), p( 3.14, 10)), S(p( 3.14, 3.456), p( 5, 10)), p( 3.14, 3.456)); - check_intersection (S(p( 3.14, 0), p( 3.14, 10)), S(p( 5, 10), p( 3.14, 3.456)), p( 3.14, 3.456)); - check_intersection (S(p( 3.14, 0), p( 3.14, 10)), S(p( 3.14, 3.456), p( -5, 10)), p( 3.14, 3.456)); - check_intersection (S(p( 3.14, 0), p( 3.14, 10)), S(p( -5, 10), p( 3.14, 3.456)), p( 3.14, 3.456)); + check_intersection (S(p( 3, 0), p( 3, 10)), S(p( 3, 3), p( 5, 10)), p( 3, 3)); + check_intersection (S(p( 3, 0), p( 3, 10)), S(p( 5, 10), p( 3, 3)), p( 3, 3)); + check_intersection (S(p( 3, 0), p( 3, 10)), S(p( 3, 3), p( -5, 10)), p( 3, 3)); + check_intersection (S(p( 3, 0), p( 3, 10)), S(p( -5, 10), p( 3, 3)), p( 3, 3)); check_intersection (S(p( 0, 0), p( 44, 44)), S(p( 44, 44), p( 55, 55)), p( 44, 44)); check_intersection (S(p( 0, 0), p( 44, 44)), S(p( 55, 55), p( 44, 44)), p( 44, 44)); check_intersection (S(p( 44, 44), p( 0, 0)), S(p( 44, 44), p( 55, 55)), p( 44, 44)); From deee5021521a1b31dd46fd977154e29a378e40e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Oct 2021 14:40:23 +0200 Subject: [PATCH 10/14] avoid using default --- .../Intersections_2/Segment_2_Segment_2.h | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index 9d88487598e..e4eaa4652d5 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -88,8 +88,10 @@ seg_seg_do_intersect_crossing( return S2S2_inter_info(i2); case RIGHT_TURN: return S2S2_inter_info(false); - default: // LEFT_TURN + case LEFT_TURN: return S2S2_inter_info(true); + default: + CGAL_assume(false); } } case RIGHT_TURN: @@ -100,14 +102,18 @@ seg_seg_do_intersect_crossing( return S2S2_inter_info(i2); case RIGHT_TURN: return S2S2_inter_info(true); - default: // LEFT_TURN + case LEFT_TURN: return S2S2_inter_info(false); + default: + CGAL_assume(false); } } - default: //COLLINEAR + case COLLINEAR: if (extra_test && k.collinear_2_object()(p3,p4,p2)) return S2S2_inter_info(i3, i2); return S2S2_inter_info(i3); + default: + CGAL_assume(false); } CGAL_kernel_assertion(false); return S2S2_inter_info(false); @@ -143,8 +149,10 @@ seg_seg_do_intersect_contained( return S2S2_inter_info(i4); case RIGHT_TURN: return S2S2_inter_info(true); - default: // LEFT_TURN + case LEFT_TURN: return S2S2_inter_info(false); + default: + CGAL_assume(false); } } case RIGHT_TURN: @@ -155,14 +163,18 @@ seg_seg_do_intersect_contained( return S2S2_inter_info(i4); case RIGHT_TURN: return S2S2_inter_info(false); - default: // LEFT_TURN + case LEFT_TURN: return S2S2_inter_info(true); + default: + CGAL_assume(false); } } - default: // COLLINEAR + case COLLINEAR: if (extra_test && k.collinear_2_object()(p3,p4,p2)) return S2S2_inter_info(i3, i4); return S2S2_inter_info(i3); + default: + CGAL_assume(false); } CGAL_kernel_assertion(false); return S2S2_inter_info(false); @@ -214,7 +226,7 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, return S2S2_inter_info(false); case EQUAL: return S2S2_inter_info(A2_id); // DI_MORE_INFO_TAG: A2==B1 but only A2 is reported - default: // LARGER + case LARGER: switch(make_certain(compare_xy(A2,B2))) { case SMALLER: return seg_seg_do_intersect_crossing(A1,A2,B1,B2, A1_id,A2_id,B1_id+2,B2_id+2, k, extra_test); @@ -223,9 +235,14 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, if (extra_test && k.collinear_2_object()(A1, A2, B1)) return S2S2_inter_info(B1_id+2, B2_id+2); // DI_MORE_INFO_TAG: A2==B2 but only B2 is reported return S2S2_inter_info(A2_id); // DI_MORE_INFO_TAG: A2==B2 but only A2 is reported - default: // LARGER + case LARGER: return seg_seg_do_intersect_contained(A1,A2,B1,B2, A1_id,A2_id,B1_id+2,B2_id+2, k, extra_test); + default: + CGAL_assume(false); } + default: + CGAL_assume(false); + } case EQUAL: if (extra_test) @@ -239,20 +256,23 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, case EQUAL: // A1 = B1 < A2 = B2 return S2S2_inter_info(A1_id, A2_id); // DI_MORE_INFO_TAG: A1==B1 and A2==B2 but only A1 and A2 are reported - default: // LARGER + case LARGER: // A1 = B1 < B2 < A2 if (k.collinear_2_object()(A1,A2,B2)) return S2S2_inter_info(B1_id+2, B2_id+2); // DI_MORE_INFO_TAG: A1==B1 but only B1 is reported + break; + default: + CGAL_assume(false); } } return S2S2_inter_info(A1_id); // DI_MORE_INFO_TAG: A1==B1 but only A1 is reported - default: // LARGER + case LARGER: switch(make_certain(compare_xy(B2,A1))) { case SMALLER: return S2S2_inter_info(false); case EQUAL: return S2S2_inter_info(A1_id); // DI_MORE_INFO_TAG: A1==B2 but only A1 is reported - default: // LARGER + case LARGER: switch(make_certain(compare_xy(B2,A2))) { case SMALLER: return seg_seg_do_intersect_crossing(B1,B2,A1,A2, B1_id+2,B2_id+2,A1_id,A2_id, k, extra_test); @@ -261,10 +281,16 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, if (extra_test && k.collinear_2_object()(B1, A1, B2)) return S2S2_inter_info(A1_id, A2_id); // DI_MORE_INFO_TAG: A2==B2 but only A2 is reported return S2S2_inter_info(A2_id); // DI_MORE_INFO_TAG: A2==B2 but only A2 is reported - default: // LARGER + case LARGER: return seg_seg_do_intersect_contained(B1,B2,A1,A2, B1_id+2,B2_id+2,A1_id,A2_id, k, extra_test); + default: + CGAL_assume(false); } + default: + CGAL_assume(false); } + default: + CGAL_assume(false); } CGAL_kernel_assertion(false); From d370326ec19703c7c069ae60750824be5d2b450a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Oct 2021 14:45:10 +0200 Subject: [PATCH 11/14] add CGAL_unreachable as requested by @lrineau and @mglisse --- Generator/include/CGAL/point_generators_2.h | 2 +- .../CGAL/Homogeneous/Aff_transformationH2.h | 72 +++++++++---------- .../CGAL/Homogeneous/Aff_transformationH3.h | 20 +++--- .../CGAL/Intersections_2/Line_2_Segment_2.h | 2 +- .../Intersections_2/Segment_2_Segment_2.h | 24 +++---- STL_Extension/include/CGAL/assertions.h | 2 + .../test_segment_simplex_traverser_3.cpp | 2 +- .../CGAL/Rotational_sweep_visibility_2.h | 8 +-- 8 files changed, 67 insertions(+), 65 deletions(-) diff --git a/Generator/include/CGAL/point_generators_2.h b/Generator/include/CGAL/point_generators_2.h index bfa26affe5f..ea08ed3170b 100644 --- a/Generator/include/CGAL/point_generators_2.h +++ b/Generator/include/CGAL/point_generators_2.h @@ -186,7 +186,7 @@ generate_point() { this->d_item = creator( T( this->d_range), T(d)); break; default: - CGAL_assume(false); + CGAL_unreachable(); } } diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/Aff_transformationH2.h b/Homogeneous_kernel/include/CGAL/Homogeneous/Aff_transformationH2.h index a97ca83abf5..7678de819f5 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/Aff_transformationH2.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/Aff_transformationH2.h @@ -856,7 +856,7 @@ Aff_transformation_repH2::homogeneous(int i, int j) const case 0: return a; case 1: return b; case 2: return c; - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -864,7 +864,7 @@ Aff_transformation_repH2::homogeneous(int i, int j) const case 0: return d; case 1: return e; case 2: return f; - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -872,10 +872,10 @@ Aff_transformation_repH2::homogeneous(int i, int j) const case 0: return RT(0); case 1: return RT(0); case 2: return g; - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return RT(0); } @@ -900,7 +900,7 @@ Translation_repH2::homogeneous(int i, int j) const case 0: return _tv.hw(); case 1: return RT(0); case 2: return _tv.hx(); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -908,7 +908,7 @@ Translation_repH2::homogeneous(int i, int j) const case 0: return RT(0); case 1: return _tv.hw(); case 2: return _tv.hy(); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -916,10 +916,10 @@ Translation_repH2::homogeneous(int i, int j) const case 0: return RT(0); case 1: return RT(0); case 2: return _tv.hw(); - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return RT(0); } @@ -935,7 +935,7 @@ Translation_repH2::cartesian(int i, int j) const case 0: return FT(1); case 1: return FT(0); case 2: return _tv.x(); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -943,7 +943,7 @@ Translation_repH2::cartesian(int i, int j) const case 0: return FT(0); case 1: return FT(1); case 2: return _tv.y(); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -951,10 +951,10 @@ Translation_repH2::cartesian(int i, int j) const case 0: return FT(0); case 1: return FT(0); case 2: return FT(1); - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return FT(0); } @@ -971,7 +971,7 @@ homogeneous(int i, int j) const case 0: return _cos; case 1: return - _sin; case 2: return RT(0); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -979,7 +979,7 @@ homogeneous(int i, int j) const case 0: return _sin; case 1: return _cos; case 2: return RT(0); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -987,10 +987,10 @@ homogeneous(int i, int j) const case 0: return RT(0); case 1: return RT(0); case 2: return _den; - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return RT(0); } @@ -1007,7 +1007,7 @@ cartesian(int i, int j) const case 0: return FT(_cos) / FT(_den); case 1: return - FT(_sin) / FT(_den); case 2: return FT(0); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -1015,7 +1015,7 @@ cartesian(int i, int j) const case 0: return FT(_sin) / FT(_den); case 1: return FT(_cos) / FT(_den); case 2: return FT(0); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -1023,10 +1023,10 @@ cartesian(int i, int j) const case 0: return FT(0); case 1: return FT(0); case 2: return FT(1); - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return FT(0); } @@ -1043,7 +1043,7 @@ homogeneous(int i, int j) const case 0: return _sf_num; case 1: return RT(0); case 2: return RT(0); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -1051,7 +1051,7 @@ homogeneous(int i, int j) const case 0: return RT(0); case 1: return _sf_num; case 2: return RT(0); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -1059,10 +1059,10 @@ homogeneous(int i, int j) const case 0: return RT(0); case 1: return RT(0); case 2: return _sf_den; - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return RT(0); } @@ -1079,7 +1079,7 @@ cartesian(int i, int j) const case 0: return FT(_sf_num) / FT(_sf_den); case 1: return FT(0); case 2: return FT(0); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -1087,7 +1087,7 @@ cartesian(int i, int j) const case 0: return FT(0); case 1: return FT(_sf_num) / FT(_sf_den); case 2: return FT(0); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -1095,10 +1095,10 @@ cartesian(int i, int j) const case 0: return FT(0); case 1: return FT(0); case 2: return FT(1); - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return FT(0); } @@ -1116,7 +1116,7 @@ homogeneous(int i, int j) const case 0: return l.b()*l.b() - l.a()*l.a(); case 1: return l.a()*l.b()*mRT2; case 2: return l.a()*l.c()*mRT2; - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -1124,7 +1124,7 @@ homogeneous(int i, int j) const case 0: return l.a()*l.b()*mRT2; case 1: return l.a()*l.a() - l.b()*l.b(); case 2: return l.b()*l.c()*mRT2; - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -1132,10 +1132,10 @@ homogeneous(int i, int j) const case 0: return RT(0); case 1: return RT(0); case 2: return l.a()*l.a() + l.b()*l.b(); - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return RT(0); } @@ -1153,7 +1153,7 @@ cartesian(int i, int j) const case 0: return FT( l.b()-l.a() ) / FT( l.a()+l.b()); case 1: return FT( homogeneous(0,1)) / de; case 2: return FT( homogeneous(0,2)) / de; - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -1161,7 +1161,7 @@ cartesian(int i, int j) const case 0: return FT( homogeneous(1,0)) / de; case 1: return FT( l.a()-l.b() ) / FT( l.a()+l.b()); case 2: return FT( homogeneous(1,2)) / de; - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -1169,10 +1169,10 @@ cartesian(int i, int j) const case 0: return FT(0); case 1: return FT(0); case 2: return FT(1); - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return FT(0); } diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/Aff_transformationH3.h b/Homogeneous_kernel/include/CGAL/Homogeneous/Aff_transformationH3.h index f269496d79d..fa0ba377b4d 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/Aff_transformationH3.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/Aff_transformationH3.h @@ -706,7 +706,7 @@ homogeneous(int i, int j) const case 1: return t01; case 2: return t02; case 3: return t03; - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -715,7 +715,7 @@ homogeneous(int i, int j) const case 1: return t11; case 2: return t12; case 3: return t13; - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -724,7 +724,7 @@ homogeneous(int i, int j) const case 1: return t21; case 2: return t22; case 3: return t23; - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 3: switch (j) @@ -733,10 +733,10 @@ homogeneous(int i, int j) const case 1: return RT0; case 2: return RT0; case 3: return t33; - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return RT0; } @@ -864,7 +864,7 @@ Translation_repH3::homogeneous(int i, int j) const case 1: return RT0; case 2: return RT0; case 3: return tv.hx(); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 1: switch (j) @@ -873,7 +873,7 @@ Translation_repH3::homogeneous(int i, int j) const case 1: return tv.hw(); case 2: return RT0; case 3: return tv.hy(); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 2: switch (j) @@ -882,7 +882,7 @@ Translation_repH3::homogeneous(int i, int j) const case 1: return RT0; case 2: return tv.hw(); case 3: return tv.hz(); - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case 3: switch (j) @@ -891,10 +891,10 @@ Translation_repH3::homogeneous(int i, int j) const case 1: return RT0; case 2: return RT0; case 3: return tv.hw(); - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return RT0; } diff --git a/Intersections_2/include/CGAL/Intersections_2/Line_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Line_2_Segment_2.h index 0c5d881b544..5c2850af7a8 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Line_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Line_2_Segment_2.h @@ -125,7 +125,7 @@ Segment_2_Line_2_pair::intersection_type() const _result = SEGMENT; break; default: - CGAL_assume(false); + CGAL_unreachable(); } return _result; } diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index e4eaa4652d5..d912b2faf30 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -91,7 +91,7 @@ seg_seg_do_intersect_crossing( case LEFT_TURN: return S2S2_inter_info(true); default: - CGAL_assume(false); + CGAL_unreachable(); } } case RIGHT_TURN: @@ -105,7 +105,7 @@ seg_seg_do_intersect_crossing( case LEFT_TURN: return S2S2_inter_info(false); default: - CGAL_assume(false); + CGAL_unreachable(); } } case COLLINEAR: @@ -113,7 +113,7 @@ seg_seg_do_intersect_crossing( return S2S2_inter_info(i3, i2); return S2S2_inter_info(i3); default: - CGAL_assume(false); + CGAL_unreachable(); } CGAL_kernel_assertion(false); return S2S2_inter_info(false); @@ -152,7 +152,7 @@ seg_seg_do_intersect_contained( case LEFT_TURN: return S2S2_inter_info(false); default: - CGAL_assume(false); + CGAL_unreachable(); } } case RIGHT_TURN: @@ -166,7 +166,7 @@ seg_seg_do_intersect_contained( case LEFT_TURN: return S2S2_inter_info(true); default: - CGAL_assume(false); + CGAL_unreachable(); } } case COLLINEAR: @@ -174,7 +174,7 @@ seg_seg_do_intersect_contained( return S2S2_inter_info(i3, i4); return S2S2_inter_info(i3); default: - CGAL_assume(false); + CGAL_unreachable(); } CGAL_kernel_assertion(false); return S2S2_inter_info(false); @@ -238,10 +238,10 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, case LARGER: return seg_seg_do_intersect_contained(A1,A2,B1,B2, A1_id,A2_id,B1_id+2,B2_id+2, k, extra_test); default: - CGAL_assume(false); + CGAL_unreachable(); } default: - CGAL_assume(false); + CGAL_unreachable(); } case EQUAL: @@ -262,7 +262,7 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, return S2S2_inter_info(B1_id+2, B2_id+2); // DI_MORE_INFO_TAG: A1==B1 but only B1 is reported break; default: - CGAL_assume(false); + CGAL_unreachable(); } } return S2S2_inter_info(A1_id); // DI_MORE_INFO_TAG: A1==B1 but only A1 is reported @@ -284,13 +284,13 @@ do_intersect_with_info(const typename K::Segment_2 &seg1, case LARGER: return seg_seg_do_intersect_contained(B1,B2,A1,A2, B1_id+2,B2_id+2,A1_id,A2_id, k, extra_test); default: - CGAL_assume(false); + CGAL_unreachable(); } default: - CGAL_assume(false); + CGAL_unreachable(); } default: - CGAL_assume(false); + CGAL_unreachable(); } CGAL_kernel_assertion(false); diff --git a/STL_Extension/include/CGAL/assertions.h b/STL_Extension/include/CGAL/assertions.h index 90ea7557ed6..f76fdb967e1 100644 --- a/STL_Extension/include/CGAL/assertions.h +++ b/STL_Extension/include/CGAL/assertions.h @@ -106,6 +106,8 @@ inline bool possibly(Uncertain c); # define CGAL_assume_code(CODE) CGAL_assertion_code(CODE) #endif // no CGAL_NO_ASSERTIONS +#define CGAL_unreachable() CGAL_assume(false) + # define CGAL_static_assertion(EX) \ static_assert(EX, #EX) diff --git a/Triangulation_3/test/Triangulation_3/test_segment_simplex_traverser_3.cpp b/Triangulation_3/test/Triangulation_3/test_segment_simplex_traverser_3.cpp index 375b8096617..eb1fa780be4 100644 --- a/Triangulation_3/test/Triangulation_3/test_segment_simplex_traverser_3.cpp +++ b/Triangulation_3/test/Triangulation_3/test_segment_simplex_traverser_3.cpp @@ -144,7 +144,7 @@ bool test(const DT& dt, break; } default: - CGAL_assume(false); + CGAL_unreachable(); } // end switch } } diff --git a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h index 521565ba3bb..2ee98969576 100644 --- a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h +++ b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h @@ -120,7 +120,7 @@ private: return 1; case LEFT_TURN: return 2; - default: CGAL_assume(false); + default: CGAL_unreachable(); } return -1; } @@ -215,7 +215,7 @@ private: == Visibility_2::orientation_2(geom_traits, s2, t2, s1); else return true; - default: CGAL_assume(false); + default: CGAL_unreachable(); } break; case LEFT_TURN: @@ -234,11 +234,11 @@ private: == Visibility_2::orientation_2(geom_traits, s2, t2, s1); else return true; - default: CGAL_assume(false); + default: CGAL_unreachable(); } } - CGAL_assume(false); + CGAL_unreachable(); return false; } From 604d2fd1ffcd0072958ba53b606d80fe7b993883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Oct 2021 15:19:05 +0200 Subject: [PATCH 12/14] direct definition the extra if was generating fallthru warnings --- Installation/include/CGAL/config.h | 4 +++- STL_Extension/include/CGAL/assertions.h | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Installation/include/CGAL/config.h b/Installation/include/CGAL/config.h index 33350489671..daab1608122 100644 --- a/Installation/include/CGAL/config.h +++ b/Installation/include/CGAL/config.h @@ -369,15 +369,17 @@ using std::max; # define CGAL_NO_UNIQUE_ADDRESS #endif -// Macro CGAL_ASSUME +// Macro CGAL_ASSUME and CGAL_unreachable // Call a builtin of the compiler to pass a hint to the compiler #if __has_builtin(__builtin_unreachable) || (CGAL_GCC_VERSION > 0 && !__STRICT_ANSI__) // From g++ 4.5, there exists a __builtin_unreachable() // Also in LLVM/clang # define CGAL_ASSUME(EX) if(!(EX)) { __builtin_unreachable(); } +# define CGAL_unreachable() __builtin_unreachable() #elif defined(_MSC_VER) // MSVC has __assume # define CGAL_ASSUME(EX) __assume(EX) +# define CGAL_unreachable() __assume(0) #endif // If CGAL_ASSUME is not defined, then CGAL_assume and CGAL_assume_code are // defined differently, in diff --git a/STL_Extension/include/CGAL/assertions.h b/STL_Extension/include/CGAL/assertions.h index f76fdb967e1..293a2abe557 100644 --- a/STL_Extension/include/CGAL/assertions.h +++ b/STL_Extension/include/CGAL/assertions.h @@ -84,6 +84,7 @@ inline bool possibly(Uncertain c); # define CGAL_assume_code(CODE) CODE # else // not def CGAL_ASSUME # define CGAL_assume(EX) CGAL_assertion(EX) +# define CGAL_unreachable() CGAL_assertion(false) # define CGAL_assume_code(CODE) CGAL_assertion_code(CODE) # endif // not def CGAL_ASSUME #else // no CGAL_NO_ASSERTIONS @@ -106,8 +107,6 @@ inline bool possibly(Uncertain c); # define CGAL_assume_code(CODE) CGAL_assertion_code(CODE) #endif // no CGAL_NO_ASSERTIONS -#define CGAL_unreachable() CGAL_assume(false) - # define CGAL_static_assertion(EX) \ static_assert(EX, #EX) From 85c00352c39e12a9d094de50aead311ceb6dccac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Oct 2021 16:01:19 +0200 Subject: [PATCH 13/14] separate macros and macro function --- Installation/include/CGAL/config.h | 6 +++--- STL_Extension/include/CGAL/assertions.h | 24 ++++++++++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Installation/include/CGAL/config.h b/Installation/include/CGAL/config.h index daab1608122..2b392b6d8ca 100644 --- a/Installation/include/CGAL/config.h +++ b/Installation/include/CGAL/config.h @@ -369,17 +369,17 @@ using std::max; # define CGAL_NO_UNIQUE_ADDRESS #endif -// Macro CGAL_ASSUME and CGAL_unreachable +// Macro CGAL_ASSUME and CGAL_UNREACHABLE // Call a builtin of the compiler to pass a hint to the compiler #if __has_builtin(__builtin_unreachable) || (CGAL_GCC_VERSION > 0 && !__STRICT_ANSI__) // From g++ 4.5, there exists a __builtin_unreachable() // Also in LLVM/clang # define CGAL_ASSUME(EX) if(!(EX)) { __builtin_unreachable(); } -# define CGAL_unreachable() __builtin_unreachable() +# define CGAL_UNREACHABLE() __builtin_unreachable() #elif defined(_MSC_VER) // MSVC has __assume # define CGAL_ASSUME(EX) __assume(EX) -# define CGAL_unreachable() __assume(0) +# define CGAL_UNREACHABLE() __assume(0) #endif // If CGAL_ASSUME is not defined, then CGAL_assume and CGAL_assume_code are // defined differently, in diff --git a/STL_Extension/include/CGAL/assertions.h b/STL_Extension/include/CGAL/assertions.h index 293a2abe557..e7357ecd8d1 100644 --- a/STL_Extension/include/CGAL/assertions.h +++ b/STL_Extension/include/CGAL/assertions.h @@ -79,14 +79,6 @@ inline bool possibly(Uncertain c); # define CGAL_destructor_assertion_catch(CODE) CODE # define CGAL_assertion_msg(EX,MSG) (static_cast(0)) # define CGAL_assertion_code(CODE) -# ifdef CGAL_ASSUME -# define CGAL_assume(EX) CGAL_ASSUME(EX) -# define CGAL_assume_code(CODE) CODE -# else // not def CGAL_ASSUME -# define CGAL_assume(EX) CGAL_assertion(EX) -# define CGAL_unreachable() CGAL_assertion(false) -# define CGAL_assume_code(CODE) CGAL_assertion_code(CODE) -# endif // not def CGAL_ASSUME #else // no CGAL_NO_ASSERTIONS # define CGAL_ASSERTIONS_ENABLED true # define CGAL_assertion(EX) \ @@ -103,10 +95,22 @@ inline bool possibly(Uncertain c); # define CGAL_assertion_msg(EX,MSG) \ (CGAL::possibly(EX)?(static_cast(0)): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__, MSG)) # define CGAL_assertion_code(CODE) CODE -# define CGAL_assume(EX) CGAL_assertion(EX) -# define CGAL_assume_code(CODE) CGAL_assertion_code(CODE) #endif // no CGAL_NO_ASSERTIONS +# ifdef CGAL_ASSUME +# define CGAL_assume(EX) CGAL_ASSUME(EX) +# define CGAL_assume_code(CODE) CODE +# else // not def CGAL_ASSUME +# define CGAL_assume(EX) CGAL_assertion(EX) +# define CGAL_assume_code(CODE) CGAL_assertion_code(CODE) +# endif // CGAL_ASSUME + +# ifdef CGAL_UNREACHABLE +# define CGAL_unreachable() CGAL_UNREACHABLE() +# else // not def CGAL_UNREACHABLE +# define CGAL_unreachable() CGAL_assertion(false) +# endif // CGAL_UNREACHABLE + # define CGAL_static_assertion(EX) \ static_assert(EX, #EX) From 2d9280ec9681637e45f04a2b60e141f489628e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Oct 2021 16:09:32 +0200 Subject: [PATCH 14/14] do not modify CGAL_assume --- STL_Extension/include/CGAL/assertions.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/STL_Extension/include/CGAL/assertions.h b/STL_Extension/include/CGAL/assertions.h index e7357ecd8d1..45d513d9f5f 100644 --- a/STL_Extension/include/CGAL/assertions.h +++ b/STL_Extension/include/CGAL/assertions.h @@ -79,6 +79,13 @@ inline bool possibly(Uncertain c); # define CGAL_destructor_assertion_catch(CODE) CODE # define CGAL_assertion_msg(EX,MSG) (static_cast(0)) # define CGAL_assertion_code(CODE) +# ifdef CGAL_ASSUME +# define CGAL_assume(EX) CGAL_ASSUME(EX) +# define CGAL_assume_code(CODE) CODE +# else // not def CGAL_ASSUME +# define CGAL_assume(EX) CGAL_assertion(EX) +# define CGAL_assume_code(CODE) CGAL_assertion_code(CODE) +# endif // not def CGAL_ASSUME #else // no CGAL_NO_ASSERTIONS # define CGAL_ASSERTIONS_ENABLED true # define CGAL_assertion(EX) \ @@ -95,16 +102,10 @@ inline bool possibly(Uncertain c); # define CGAL_assertion_msg(EX,MSG) \ (CGAL::possibly(EX)?(static_cast(0)): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__, MSG)) # define CGAL_assertion_code(CODE) CODE +# define CGAL_assume(EX) CGAL_assertion(EX) +# define CGAL_assume_code(CODE) CGAL_assertion_code(CODE) #endif // no CGAL_NO_ASSERTIONS -# ifdef CGAL_ASSUME -# define CGAL_assume(EX) CGAL_ASSUME(EX) -# define CGAL_assume_code(CODE) CODE -# else // not def CGAL_ASSUME -# define CGAL_assume(EX) CGAL_assertion(EX) -# define CGAL_assume_code(CODE) CGAL_assertion_code(CODE) -# endif // CGAL_ASSUME - # ifdef CGAL_UNREACHABLE # define CGAL_unreachable() CGAL_UNREACHABLE() # else // not def CGAL_UNREACHABLE