From f25545b58e54857f56cfe90769d9bdafe4bca731 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 24 Feb 2024 14:07:50 +0100 Subject: [PATCH] Use if constexpr macro instead of condition macro. --- .../detail/convex_hull/interface.hpp | 4 +- .../distance/geometry_to_segment_or_box.hpp | 39 ++- .../detail/distance/segment_to_box.hpp | 28 +- .../detail/distance/segment_to_segment.hpp | 29 +- .../algorithms/detail/is_valid/pointlike.hpp | 31 +- .../algorithms/detail/is_valid/polygon.hpp | 60 ++-- .../overlay/append_no_dups_or_spikes.hpp | 50 +-- .../detail/overlay/cluster_exits.hpp | 16 +- .../detail/overlay/get_turn_info.hpp | 307 ++++++++--------- .../detail/overlay/get_turn_info_la.hpp | 314 ++++++++++-------- .../detail/overlay/get_turn_info_ll.hpp | 98 +++--- .../detail/overlay/handle_colocations.hpp | 17 +- .../detail/overlay/pointlike_pointlike.hpp | 16 +- .../detail/overlay/sort_by_side.hpp | 6 +- .../algorithms/detail/overlay/traversal.hpp | 162 ++++----- .../overlay/traversal_switch_detector.hpp | 30 +- .../detail/point_is_spike_or_equal.hpp | 78 +++-- .../algorithms/detail/relate/linear_areal.hpp | 95 +++--- .../algorithms/detail/relate/point_point.hpp | 8 +- .../algorithms/detail/relate/result.hpp | 11 +- .../algorithms/detail/within/multi_point.hpp | 13 +- .../geometry/algorithms/line_interpolate.hpp | 13 +- .../geometry/algorithms/remove_spikes.hpp | 8 +- .../boost/geometry/algorithms/simplify.hpp | 29 +- .../geometry/formulas/andoyer_inverse.hpp | 15 +- .../boost/geometry/formulas/area_formulas.hpp | 42 ++- .../formulas/differential_quantities.hpp | 10 +- .../boost/geometry/formulas/karney_direct.hpp | 8 +- .../geometry/formulas/karney_inverse.hpp | 35 +- .../geometry/formulas/meridian_direct.hpp | 8 +- .../boost/geometry/formulas/thomas_direct.hpp | 19 +- .../geometry/formulas/thomas_inverse.hpp | 15 +- .../geometry/formulas/vincenty_direct.hpp | 12 +- .../geometry/formulas/vincenty_inverse.hpp | 15 +- .../geometry/index/detail/rtree/node/node.hpp | 15 +- .../index/detail/rtree/pack_create.hpp | 11 +- .../index/detail/rtree/visitors/insert.hpp | 24 +- .../is_valid/failing_reason_policy.hpp | 7 +- .../srs/projections/impl/pj_transform.hpp | 4 +- .../strategies/spherical/point_order.hpp | 5 +- include/boost/geometry/util/precise_math.hpp | 12 +- 41 files changed, 909 insertions(+), 810 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp index 884a9278b3..e141036141 100644 --- a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp +++ b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp @@ -53,7 +53,7 @@ #include #include -#include +#include #include #include #include @@ -240,7 +240,7 @@ struct convex_hull geometry::detail::assign_box_corners_oriented(box, arr); std::move(arr.begin(), arr.end(), range::back_inserter(out)); - if (BOOST_GEOMETRY_CONDITION(Close)) + if BOOST_GEOMETRY_CONSTEXPR (Close) { range::push_back(out, range::front(out)); } diff --git a/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp b/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp index 5af854f901..8d5d8b57cc 100644 --- a/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2021, Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2014-2021, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -35,7 +36,7 @@ #include #include -#include +#include namespace boost { namespace geometry @@ -247,26 +248,28 @@ class geometry_to_segment_or_box } } - if (BOOST_GEOMETRY_CONDITION(is_comparable::value)) + if BOOST_GEOMETRY_CONSTEXPR (is_comparable::value) { return (std::min)(cd_min1, cd_min2); } - - if (cd_min1 < cd_min2) - { - return strategy.apply(*pit_min, *it_min1, *it_min2); - } - else + else // else prevents unreachable code warning { - return dispatch::distance - < - segment_or_box_point, - typename std::iterator_traits - < - segment_iterator_type - >::value_type, - Strategies - >::apply(*it_min, *sit_min, strategies); + if (cd_min1 < cd_min2) + { + return strategy.apply(*pit_min, *it_min1, *it_min2); + } + else + { + return dispatch::distance + < + segment_or_box_point, + typename std::iterator_traits + < + segment_iterator_type + >::value_type, + Strategies + >::apply(*it_min, *sit_min, strategies); + } } } diff --git a/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp b/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp index 09f3cc4f61..442ea6f954 100644 --- a/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp @@ -1,5 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) +// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland. + // Copyright (c) 2014-2023 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle @@ -41,7 +43,7 @@ #include #include -#include +#include #include #include @@ -154,21 +156,23 @@ class segment_to_box_2D_generic } } - if (BOOST_GEOMETRY_CONDITION(is_comparable::value)) + if BOOST_GEOMETRY_CONSTEXPR (is_comparable::value) { return cd[imin]; } - - if (imin < 4) - { - return strategy.apply(box_points[imin], p[0], p[1]); - } - else + else // else prevents unreachable code warning { - unsigned int bimin = imin - 4; - return strategy.apply(p[bimin], - *bit_min[bimin].first, - *bit_min[bimin].second); + if (imin < 4) + { + return strategy.apply(box_points[imin], p[0], p[1]); + } + else + { + unsigned int bimin = imin - 4; + return strategy.apply(p[bimin], + *bit_min[bimin].first, + *bit_min[bimin].second); + } } } }; diff --git a/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp b/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp index 9cbececdb7..f308e58210 100644 --- a/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp +++ b/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2021, Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2014-2021, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -28,7 +29,7 @@ #include #include -#include +#include namespace boost { namespace geometry @@ -82,21 +83,23 @@ class segment_to_segment std::size_t imin = std::distance(boost::addressof(d[0]), std::min_element(d, d + 4)); - if (BOOST_GEOMETRY_CONDITION(is_comparable::value)) + if BOOST_GEOMETRY_CONSTEXPR (is_comparable::value) { return d[imin]; } - - switch (imin) + else // else prevents unreachable code warning { - case 0: - return strategy.apply(q[0], p[0], p[1]); - case 1: - return strategy.apply(q[1], p[0], p[1]); - case 2: - return strategy.apply(p[0], q[0], q[1]); - default: - return strategy.apply(p[1], q[0], q[1]); + switch (imin) + { + case 0: + return strategy.apply(q[0], p[0], p[1]); + case 1: + return strategy.apply(q[1], p[0], p[1]); + case 2: + return strategy.apply(p[0], q[0], q[1]); + default: + return strategy.apply(p[1], q[0], q[1]); + } } } }; diff --git a/include/boost/geometry/algorithms/detail/is_valid/pointlike.hpp b/include/boost/geometry/algorithms/detail/is_valid/pointlike.hpp index c0cf239c25..f4523454ac 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/pointlike.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/pointlike.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2020, Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2014-2020, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -20,7 +21,7 @@ #include #include -#include +#include namespace boost { namespace geometry @@ -63,21 +64,21 @@ struct is_valid { boost::ignore_unused(multipoint, visitor); - if (BOOST_GEOMETRY_CONDITION( - AllowEmptyMultiGeometries || !boost::empty(multipoint))) - { - // we allow empty multi-geometries, so an empty multipoint - // is considered valid - return ! detail::is_valid::has_invalid_coordinate - < - MultiPoint - >::apply(multipoint, visitor); - } - else + if BOOST_GEOMETRY_CONSTEXPR (! AllowEmptyMultiGeometries) { - // we do not allow an empty multipoint - return visitor.template apply(); + if (boost::empty(multipoint)) + { + // we do not allow an empty multipoint + return visitor.template apply(); + } } + + // if we allow empty multi-geometries, an empty multipoint + // is considered valid + return ! detail::is_valid::has_invalid_coordinate + < + MultiPoint + >::apply(multipoint, visitor); } }; diff --git a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp index 39512ad154..006581aa3b 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp @@ -450,42 +450,44 @@ class is_valid_polygon { return true; } + else // else prevents unreachable code warning + { + // compute turns and check if all are acceptable + typedef debug_validity_phase debug_phase; + debug_phase::apply(3); - // compute turns and check if all are acceptable - typedef debug_validity_phase debug_phase; - debug_phase::apply(3); - - typedef has_valid_self_turns has_valid_turns; + typedef has_valid_self_turns has_valid_turns; - std::deque turns; - bool has_invalid_turns - = ! has_valid_turns::apply(polygon, turns, visitor, strategy); - debug_print_turns(turns.begin(), turns.end()); + std::deque turns; + bool has_invalid_turns + = ! has_valid_turns::apply(polygon, turns, visitor, strategy); + debug_print_turns(turns.begin(), turns.end()); - if (has_invalid_turns) - { - return false; - } + if (has_invalid_turns) + { + return false; + } - // check if all interior rings are inside the exterior ring - debug_phase::apply(4); + // check if all interior rings are inside the exterior ring + debug_phase::apply(4); - if (! has_holes_inside::apply(polygon, - turns.begin(), turns.end(), - visitor, - strategy)) - { - return false; - } + if (! has_holes_inside::apply(polygon, + turns.begin(), turns.end(), + visitor, + strategy)) + { + return false; + } - // check whether the interior of the polygon is a connected set - debug_phase::apply(5); + // check whether the interior of the polygon is a connected set + debug_phase::apply(5); - return has_connected_interior::apply(polygon, - turns.begin(), - turns.end(), - visitor, - strategy); + return has_connected_interior::apply(polygon, + turns.begin(), + turns.end(), + visitor, + strategy); + } } }; diff --git a/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp b/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp index c52266c190..6596104af4 100644 --- a/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp @@ -1,10 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2014-2020. // Modifications copyright (c) 2014-2020 Oracle and/or its affiliates. - // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -29,7 +29,7 @@ #include -#include +#include #include @@ -53,30 +53,32 @@ inline bool points_equal_or_close(Point1 const& point1, return true; } - if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled)) + if BOOST_GEOMETRY_CONSTEXPR (! RobustPolicy::enabled) { return false; } - - // Try using specified robust policy - typedef typename geometry::robust_point_type - < - Point1, - RobustPolicy - >::type robust_point_type; - - robust_point_type point1_rob, point2_rob; - geometry::recalculate(point1_rob, point1, robust_policy); - geometry::recalculate(point2_rob, point2, robust_policy); - - // Only if this is the case the same strategy can be used. - BOOST_STATIC_ASSERT((std::is_same - < - typename geometry::cs_tag::type, - typename geometry::cs_tag::type - >::value)); - - return detail::equals::equals_point_point(point1_rob, point2_rob, strategy); + else // else prevents unreachable code warning + { + // Try using specified robust policy + using robust_point_type = typename geometry::robust_point_type + < + Point1, + RobustPolicy + >::type; + + robust_point_type point1_rob, point2_rob; + geometry::recalculate(point1_rob, point1, robust_policy); + geometry::recalculate(point2_rob, point2, robust_policy); + + // Only if this is the case the same strategy can be used. + BOOST_STATIC_ASSERT((std::is_same + < + typename geometry::cs_tag::type, + typename geometry::cs_tag::type + >::value)); + + return detail::equals::equals_point_point(point1_rob, point2_rob, strategy); + } } @@ -214,7 +216,7 @@ inline void remove_spikes_at_closure(Ring& ring, Strategy const& strategy, template inline void fix_closure(Ring& ring, Strategy const& strategy) { - if (BOOST_GEOMETRY_CONDITION(geometry::closure::value == geometry::open)) + if BOOST_GEOMETRY_CONSTEXPR (geometry::closure::value == geometry::open) { if (! boost::empty(ring) && detail::equals::equals_point_point(range::front(ring), range::back(ring), strategy)) diff --git a/include/boost/geometry/algorithms/detail/overlay/cluster_exits.hpp b/include/boost/geometry/algorithms/detail/overlay/cluster_exits.hpp index b1c7de217d..94fe235d4e 100644 --- a/include/boost/geometry/algorithms/detail/overlay/cluster_exits.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/cluster_exits.hpp @@ -1,6 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2020-2023. // Modifications copyright (c) 2020-2023 Oracle and/or its affiliates. @@ -24,7 +25,7 @@ #include #include #include -#include +#include #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) \ || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT) \ @@ -199,13 +200,14 @@ public : // Points to different target return false; } - if (first_run - && BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer) - && target.turn_index >= 0) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer) { - // Target already assigned, so there are more targets - // or more ways to the same target - return false; + if (first_run && target.turn_index >= 0) + { + // Target already assigned, so there are more targets + // or more ways to the same target + return false; + } } target = lti; diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp index 0fa6bdbd1b..dfc87d2fa4 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp @@ -1,7 +1,7 @@ // Boost.Geometry // Copyright (c) 2007-2023 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2015-2022. // Modifications copyright (c) 2015-2022 Oracle and/or its affiliates. @@ -27,7 +27,7 @@ #include #include -#include +#include namespace boost { namespace geometry @@ -286,7 +286,7 @@ struct turn_info_verification_functions std::size_t index_p, std::size_t index_q, TurnInfo& ti) { - if (BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_side_verification)) + if BOOST_GEOMETRY_CONSTEXPR (VerifyPolicy::use_side_verification) { set_both_verified(range_p, range_q, umbrella_strategy, index_p, index_q, ti); @@ -309,29 +309,29 @@ struct turn_info_verification_functions UmbrellaStrategy const& umbrella_strategy, int index_p, int index_q) { - if (side == 0 - && BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_side_verification)) + if BOOST_GEOMETRY_CONSTEXPR (VerifyPolicy::use_side_verification) { - if (index_p >= 1 && range_p.is_last_segment()) + if (side == 0) { - return 0; - } - if (index_q >= 2 && range_q.is_last_segment()) - { - return 0; - } + if (index_p >= 1 && range_p.is_last_segment()) + { + return 0; + } + if (index_q >= 2 && range_q.is_last_segment()) + { + return 0; + } - auto const dm = get_distance_measure(range_p.at(index_p), - range_p.at(index_p + 1), - range_q.at(index_q), - umbrella_strategy); - static decltype(dm.measure) const zero = 0; - return dm.measure == zero ? 0 : dm.measure > zero ? 1 : -1; - } - else - { - return side; + auto const dm = get_distance_measure(range_p.at(index_p), + range_p.at(index_p + 1), + range_q.at(index_q), + umbrella_strategy); + static decltype(dm.measure) const zero = 0; + return dm.measure == zero ? 0 : dm.measure > zero ? 1 : -1; + } } + + return side; } }; @@ -354,45 +354,47 @@ struct touch_interior : public base_turn_handler static bool handle_as_touch(IntersectionInfo const& info, UniqueSubRange const& non_touching_range) { - if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_handle_as_touch)) + if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_handle_as_touch) { return false; } + else // else prevents unreachable code warning + { + // + // + // ^ Q(i) ^ P(i) + // \ / + // \ / + // \ / + // \ / + // \ / + // \ / + // \ / + // \ / + // \ / + // \ / it is about buffer_rt_r + // P(k) v/ they touch here "in the middle", but at the intersection... + // <---------------->v there is no follow up IP + // / + // / + // / + // / + // / + // / + // v Q(k) + // - // - // - // ^ Q(i) ^ P(i) - // \ / - // \ / - // \ / - // \ / - // \ / - // \ / - // \ / - // \ / - // \ / - // \ / it is about buffer_rt_r - // P(k) v/ they touch here "in the middle", but at the intersection... - // <---------------->v there is no follow up IP - // / - // / - // / - // / - // / - // / - // v Q(k) - // - - // Measure where the IP is located. If it is really close to the end, - // then there is no space for the next IP (on P(1)/Q(2). A "from" - // intersection will be generated, but those are never handled. - // Therefore handle it as a normal touch (two segments arrive at the - // intersection point). It currently checks for zero, but even a - // distance a little bit larger would do. - auto const dm = fun::distance_measure(info.intersections[0], non_touching_range.at(1)); - decltype(dm) const zero = 0; - bool const result = math::equals(dm, zero); - return result; + // Measure where the IP is located. If it is really close to the end, + // then there is no space for the next IP (on P(1)/Q(2). A "from" + // intersection will be generated, but those are never handled. + // Therefore handle it as a normal touch (two segments arrive at the + // intersection point). It currently checks for zero, but even a + // distance a little bit larger would do. + auto const dm = fun::distance_measure(info.intersections[0], non_touching_range.at(1)); + decltype(dm) const zero = 0; + bool const result = math::equals(dm, zero); + return result; + } } // Index: 0, P is the interior, Q is touching and vice versa @@ -561,65 +563,67 @@ struct touch : public base_turn_handler UmbrellaStrategy const& umbrella_strategy, TurnInfo& ti) { - if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_handle_imperfect_touch)) + if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_handle_imperfect_touch) { return false; } - - // Q - // ^ - // || - // || - // |^---- - // >----->P - // * * they touch here (P/Q are (nearly) on top) - // - // Q continues from where P comes. - // P continues from where Q comes - // This is often a blocking situation, - // unless there are FP issues: there might be a distance - // between Pj and Qj, in that case handle it as a union. - // - // Exaggerated: - // Q - // ^ Q is nearly vertical - // \ but not completely - and still ends above P - // | \qj In this case it should block P and - // | ^------ set Q to Union - // >----->P qj is LEFT of P1 and pi is LEFT of Q2 - // (the other way round is also possible) - - auto has_distance = [&](auto const& r1, auto const& r2) -> bool + else // else prevents unreachable code warning { - auto const d1 = get_distance_measure(r1.at(0), r1.at(1), r2.at(1), umbrella_strategy); - auto const d2 = get_distance_measure(r2.at(1), r2.at(2), r1.at(0), umbrella_strategy); - return d1.measure > 0 && d2.measure > 0; - }; + // Q + // ^ + // || + // || + // |^---- + // >----->P + // * * they touch here (P/Q are (nearly) on top) + // + // Q continues from where P comes. + // P continues from where Q comes + // This is often a blocking situation, + // unless there are FP issues: there might be a distance + // between Pj and Qj, in that case handle it as a union. + // + // Exaggerated: + // Q + // ^ Q is nearly vertical + // \ but not completely - and still ends above P + // | \qj In this case it should block P and + // | ^------ set Q to Union + // >----->P qj is LEFT of P1 and pi is LEFT of Q2 + // (the other way round is also possible) + + auto has_distance = [&](auto const& r1, auto const& r2) -> bool + { + auto const d1 = get_distance_measure(r1.at(0), r1.at(1), r2.at(1), umbrella_strategy); + auto const d2 = get_distance_measure(r2.at(1), r2.at(2), r1.at(0), umbrella_strategy); + return d1.measure > 0 && d2.measure > 0; + }; - if (side_pk_q2 == -1 && has_distance(range_p, range_q)) - { - // Even though there is a touch, Q(j) is left of P1 - // and P(i) is still left from Q2. - // Q continues to the right. - // It can continue. - ti.operations[0].operation = operation_blocked; - // Q turns right -> union (both independent), - // Q turns left -> intersection - ti.operations[1].operation = operation_union; - ti.touch_only = true; - return true; - } + if (side_pk_q2 == -1 && has_distance(range_p, range_q)) + { + // Even though there is a touch, Q(j) is left of P1 + // and P(i) is still left from Q2. + // Q continues to the right. + // It can continue. + ti.operations[0].operation = operation_blocked; + // Q turns right -> union (both independent), + // Q turns left -> intersection + ti.operations[1].operation = operation_union; + ti.touch_only = true; + return true; + } - if (side_pk_q2 == 1 && has_distance(range_q, range_p)) - { - // Similarly, but the other way round. - // Q continues to the left. - ti.operations[0].operation = operation_union; - ti.operations[1].operation = operation_blocked; - ti.touch_only = true; - return true; + if (side_pk_q2 == 1 && has_distance(range_q, range_p)) + { + // Similarly, but the other way round. + // Q continues to the left. + ti.operations[0].operation = operation_union; + ti.operations[1].operation = operation_blocked; + ti.touch_only = true; + return true; + } + return false; } - return false; } template @@ -915,39 +919,40 @@ struct start : public base_turn_handler SideCalculator const& side, UmbrellaStrategy const& ) { - if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_start_turn)) + if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_start_turn) { return false; } + else // else prevents unreachable code warning + { + // Start turns have either how_a = -1, or how_b = -1 (either p leaves or q leaves) + BOOST_GEOMETRY_ASSERT(dir_info.how_a != dir_info.how_b); + BOOST_GEOMETRY_ASSERT(dir_info.how_a == -1 || dir_info.how_b == -1); + BOOST_GEOMETRY_ASSERT(dir_info.how_a == 0 || dir_info.how_b == 0); - // Start turns have either how_a = -1, or how_b = -1 (either p leaves or q leaves) - BOOST_GEOMETRY_ASSERT(dir_info.how_a != dir_info.how_b); - BOOST_GEOMETRY_ASSERT(dir_info.how_a == -1 || dir_info.how_b == -1); - BOOST_GEOMETRY_ASSERT(dir_info.how_a == 0 || dir_info.how_b == 0); + if (dir_info.how_b == -1) + { + // p ---------------> + // | + // | q q leaves + // v + // - if (dir_info.how_b == -1) - { - // p ---------------> - // | - // | q q leaves - // v - // + int const side_qj_p1 = side.qj_wrt_p1(); + ui_else_iu(side_qj_p1 == -1, ti); + } + else if (dir_info.how_a == -1) + { + // p leaves + int const side_pj_q1 = side.pj_wrt_q1(); + ui_else_iu(side_pj_q1 == 1, ti); + } - int const side_qj_p1 = side.qj_wrt_p1(); - ui_else_iu(side_qj_p1 == -1, ti); - } - else if (dir_info.how_a == -1) - { - // p leaves - int const side_pj_q1 = side.pj_wrt_q1(); - ui_else_iu(side_pj_q1 == 1, ti); + // Copy intersection point + assign_point_and_correct(ti, method_start, info, dir_info); + return true; } - - // Copy intersection point - assign_point_and_correct(ti, method_start, info, dir_info); - return true; } - }; @@ -973,7 +978,7 @@ struct equal_opposite : public base_turn_handler IntersectionInfo const& intersection_info) { // For equal-opposite segments, normally don't do anything. - if (BOOST_GEOMETRY_CONDITION(AssignPolicy::include_opposite)) + if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_opposite) { tp.method = method_equal; for (unsigned int i = 0; i < 2; i++) @@ -1010,24 +1015,26 @@ struct collinear : public base_turn_handler UniqueSubRange2 const& range_q, DirInfo const& dir_info) { - if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_handle_as_equal)) + if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_handle_as_equal) { return false; } - - int const arrival_p = dir_info.arrival[0]; - int const arrival_q = dir_info.arrival[1]; - if (arrival_p * arrival_q != -1 || info.count != 2) + else // else prevents unreachable code warning { - // Code below assumes that either p or q arrives in the other segment - return false; - } + int const arrival_p = dir_info.arrival[0]; + int const arrival_q = dir_info.arrival[1]; + if (arrival_p * arrival_q != -1 || info.count != 2) + { + // Code below assumes that either p or q arrives in the other segment + return false; + } - auto const dm = arrival_p == 1 - ? fun::distance_measure(info.intersections[1], range_q.at(1)) - : fun::distance_measure(info.intersections[1], range_p.at(1)); - decltype(dm) const zero = 0; - return math::equals(dm, zero); + auto const dm = arrival_p == 1 + ? fun::distance_measure(info.intersections[1], range_q.at(1)) + : fun::distance_measure(info.intersections[1], range_p.at(1)); + decltype(dm) const zero = 0; + return math::equals(dm, zero); + } } /* @@ -1191,7 +1198,7 @@ private : // two operations blocked, so the whole point does not need // to be generated. // So return false to indicate nothing is to be done. - if (BOOST_GEOMETRY_CONDITION(AssignPolicy::include_opposite)) + if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_opposite) { tp.operations[Index].operation = operation_opposite; blocked = operation_opposite; @@ -1285,7 +1292,7 @@ private : *out++ = tp; } - if (BOOST_GEOMETRY_CONDITION(AssignPolicy::include_opposite)) + if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_opposite) { // Handle cases not yet handled above if ((arrival_q == -1 && arrival_p == 0) diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp index 90e4d0d063..c849774d6f 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2013-2020. // Modifications copyright (c) 2013-2020 Oracle and/or its affiliates. @@ -19,7 +19,7 @@ #include -#include +#include #include #include @@ -216,15 +216,17 @@ struct get_turn_info_linear_areal tp.operations[0].operation, tp.operations[1].operation); - bool ignore_spike - = calculate_spike_operation(tp.operations[0].operation, - inters, - umbrella_strategy); + bool const ignore_spike = calculate_spike_operation(tp.operations[0].operation, + inters, + umbrella_strategy); - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ignore_spike - || ! append_opposite_spikes( // for 'i' or 'c' i??? - tp, inters, out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (ignore_spike + // for 'i' or 'c' i??? + || ! append_opposite_spikes(tp, inters, out)) { *out++ = tp; } @@ -256,9 +258,12 @@ struct get_turn_info_linear_areal transformer(tp); // conditionally handle spikes - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ! append_collinear_spikes(tp, inters, - method_touch, append_equal, out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (! append_collinear_spikes(tp, inters, method_touch, + append_equal, out)) { *out++ = tp; // no spikes } @@ -319,9 +324,12 @@ struct get_turn_info_linear_areal transformer(tp); // conditionally handle spikes - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ! append_collinear_spikes(tp, inters, - method_replace, version, out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (! append_collinear_spikes(tp, inters, method_replace, + version, out)) { // no spikes *out++ = tp; @@ -333,10 +341,9 @@ struct get_turn_info_linear_areal turn_transformer_ec transformer(method_touch_interior); // conditionally handle spikes - if ( BOOST_GEOMETRY_CONDITION(handle_spikes) ) + if BOOST_GEOMETRY_CONSTEXPR (handle_spikes) { - append_opposite_spikes( - tp, inters, out); + append_opposite_spikes(tp, inters, out); } // TODO: ignore for spikes? @@ -357,7 +364,7 @@ struct get_turn_info_linear_areal case '0' : { // degenerate points - if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) ) + if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_degenerate) { only_convert::apply(tp, inters.i_info()); @@ -542,26 +549,30 @@ struct get_turn_info_linear_areal return false; } else*/ - if ( is_p_spike ) + if (is_p_spike) { - if ( BOOST_GEOMETRY_CONDITION(is_version_touches) - || inters.d_info().arrival[0] == 1 ) + bool output_spike = false; + if BOOST_GEOMETRY_CONSTEXPR (is_version_touches) { - if ( BOOST_GEOMETRY_CONDITION(is_version_touches) ) - { - tp.operations[0].is_collinear = true; - //tp.operations[1].is_collinear = false; - tp.method = method_touch; - } - else - { - tp.operations[0].is_collinear = true; - //tp.operations[1].is_collinear = false; + tp.operations[0].is_collinear = true; + //tp.operations[1].is_collinear = false; + tp.method = method_touch; - BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1); - base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1); - } + output_spike = true; + } + else if (inters.d_info().arrival[0] == 1) + { + tp.operations[0].is_collinear = true; + //tp.operations[1].is_collinear = false; + + BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1); + base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1); + + output_spike = true; + } + if (output_spike) + { tp.operations[0].operation = operation_blocked; tp.operations[1].operation = operation_continue; // boundary *out++ = tp; @@ -636,9 +647,12 @@ struct get_turn_info_linear_areal operation_type & op1 = turn.operations[1].operation; // NOTE: probably only if methods are WRT IPs, not segments! - if ( BOOST_GEOMETRY_CONDITION(IsFront) - || op0 == operation_intersection || op0 == operation_union - || op1 == operation_intersection || op1 == operation_union ) + if BOOST_GEOMETRY_CONSTEXPR (IsFront) + { + turn.method = m_method; + } + else if (op0 == operation_intersection || op0 == operation_union + || op1 == operation_intersection || op1 == operation_union) { turn.method = m_method; } @@ -724,145 +738,151 @@ struct get_turn_info_linear_areal // IP on the first point of Linear Geometry bool was_first_point_handled = false; - if ( BOOST_GEOMETRY_CONDITION(EnableFirst) - && range_p.is_first_segment() && ip0.is_pi && !ip0.is_qi ) // !q0i prevents duplication + if BOOST_GEOMETRY_CONSTEXPR (EnableFirst) { - TurnInfo tp = tp_model; - tp.operations[0].position = position_front; - tp.operations[1].position = position_middle; - - if ( opposite ) // opposite -> collinear - { - tp.operations[0].operation = operation_continue; - tp.operations[1].operation = operation_union; - tp.method = ip0.is_qj ? method_touch : method_touch_interior; - } - else + if (range_p.is_first_segment() && ip0.is_pi && ! ip0.is_qi ) // !q0i prevents duplication { - auto const sides = strategy.side(); - - // pi is the intersection point at qj or in the middle of q1 - // so consider segments - // 1. pi at qj: qi-qj-pj and qi-qj-qk - // x: qi-qj, y: qj-qk, qz: qk - // 2. pi in the middle of q1: qi-pi-pj and qi-pi-qj - // x: qi-pi, y: pi-qj, qz: qj - // qi-pi, side the same as WRT q1 - // pi-qj, side the same as WRT q1 - // qj WRT q1 is 0 - method_type replaced_method = method_none; - int side_pj_y = 0, side_pj_x = 0, side_qz_x = 0; - // 1. ip0 or pi at qj - if ( ip0.is_qj ) + TurnInfo tp = tp_model; + tp.operations[0].position = position_front; + tp.operations[1].position = position_middle; + + if ( opposite ) // opposite -> collinear { - replaced_method = method_touch; - side_pj_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(1)); // pj wrt q2 - side_pj_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1 - side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1 + tp.operations[0].operation = operation_continue; + tp.operations[1].operation = operation_union; + tp.method = ip0.is_qj ? method_touch : method_touch_interior; } - // 2. ip0 or pi in the middle of q1 else { - replaced_method = method_touch_interior; - side_pj_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1 - side_pj_x = side_pj_y; // pj wrt q1 - side_qz_x = 0; // qj wrt q1 - } + auto const sides = strategy.side(); + + // pi is the intersection point at qj or in the middle of q1 + // so consider segments + // 1. pi at qj: qi-qj-pj and qi-qj-qk + // x: qi-qj, y: qj-qk, qz: qk + // 2. pi in the middle of q1: qi-pi-pj and qi-pi-qj + // x: qi-pi, y: pi-qj, qz: qj + // qi-pi, side the same as WRT q1 + // pi-qj, side the same as WRT q1 + // qj WRT q1 is 0 + method_type replaced_method = method_none; + int side_pj_y = 0, side_pj_x = 0, side_qz_x = 0; + // 1. ip0 or pi at qj + if ( ip0.is_qj ) + { + replaced_method = method_touch; + side_pj_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(1)); // pj wrt q2 + side_pj_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1 + side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1 + } + // 2. ip0 or pi in the middle of q1 + else + { + replaced_method = method_touch_interior; + side_pj_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1 + side_pj_x = side_pj_y; // pj wrt q1 + side_qz_x = 0; // qj wrt q1 + } - std::pair operations - = get_info_e::operations_of_equal(side_pj_y, side_pj_x, side_qz_x); + std::pair operations + = get_info_e::operations_of_equal(side_pj_y, side_pj_x, side_qz_x); - tp.operations[0].operation = operations.first; - tp.operations[1].operation = operations.second; + tp.operations[0].operation = operations.first; + tp.operations[1].operation = operations.second; - turn_transformer_ec transformer(replaced_method); - transformer(tp); - } + turn_transformer_ec transformer(replaced_method); + transformer(tp); + } - // equals<> or collinear<> will assign the second point, - // we'd like to assign the first one - base_turn_handler::assign_point(tp, tp.method, inters.i_info(), 0); + // equals<> or collinear<> will assign the second point, + // we'd like to assign the first one + base_turn_handler::assign_point(tp, tp.method, inters.i_info(), 0); - // NOTE: is_collinear is not set for the first endpoint of L - // for which there is no preceding segment - // here is_p_first_ip == true - tp.operations[0].is_collinear = false; + // NOTE: is_collinear is not set for the first endpoint of L + // for which there is no preceding segment + // here is_p_first_ip == true + tp.operations[0].is_collinear = false; - *out++ = tp; + *out++ = tp; - was_first_point_handled = true; + was_first_point_handled = true; + } } // ANALYSE AND ASSIGN LAST // IP on the last point of Linear Geometry - if ( BOOST_GEOMETRY_CONDITION(EnableLast) - && range_p.is_last_segment() - && ( ip_count > 1 ? (ip1.is_pj && !ip1.is_qi) : (ip0.is_pj && !ip0.is_qi) ) ) // prevents duplication + if BOOST_GEOMETRY_CONSTEXPR (EnableLast) { - TurnInfo tp = tp_model; - - if ( inters.i_info().count > 1 ) + if (range_p.is_last_segment() + && (ip_count > 1 + ? (ip1.is_pj && ! ip1.is_qi) + : (ip0.is_pj && ! ip0.is_qi))) // prevents duplication { - //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 ); - tp.operations[0].is_collinear = true; - tp.operations[1].operation = opposite ? operation_continue : operation_union; - } - else //if ( result.template get<0>().count == 1 ) - { - auto const sides = strategy.side(); - - // pj is the intersection point at qj or in the middle of q1 - // so consider segments - // 1. pj at qj: qi-qj-pi and qi-qj-qk - // x: qi-qj, y: qj-qk, qz: qk - // 2. pj in the middle of q1: qi-pj-pi and qi-pj-qj - // x: qi-pj, y: pj-qj, qz: qj - // qi-pj, the side is the same as WRT q1 - // pj-qj, the side is the same as WRT q1 - // side of qj WRT q1 is 0 - int side_pi_y = 0, side_pi_x = 0, side_qz_x = 0; - // 1. ip0 or pj at qj - if ( ip0.is_qj ) + TurnInfo tp = tp_model; + + if ( inters.i_info().count > 1 ) { - side_pi_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(0)); // pi wrt q2 - side_pi_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1 - side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1 + //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 ); + tp.operations[0].is_collinear = true; + tp.operations[1].operation = opposite ? operation_continue : operation_union; } - // 2. ip0 or pj in the middle of q1 - else + else //if ( result.template get<0>().count == 1 ) { - side_pi_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1 - side_pi_x = side_pi_y; // pi wrt q1 - side_qz_x = 0; // qj wrt q1 - } + auto const sides = strategy.side(); + + // pj is the intersection point at qj or in the middle of q1 + // so consider segments + // 1. pj at qj: qi-qj-pi and qi-qj-qk + // x: qi-qj, y: qj-qk, qz: qk + // 2. pj in the middle of q1: qi-pj-pi and qi-pj-qj + // x: qi-pj, y: pj-qj, qz: qj + // qi-pj, the side is the same as WRT q1 + // pj-qj, the side is the same as WRT q1 + // side of qj WRT q1 is 0 + int side_pi_y = 0, side_pi_x = 0, side_qz_x = 0; + // 1. ip0 or pj at qj + if ( ip0.is_qj ) + { + side_pi_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(0)); // pi wrt q2 + side_pi_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1 + side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1 + } + // 2. ip0 or pj in the middle of q1 + else + { + side_pi_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1 + side_pi_x = side_pi_y; // pi wrt q1 + side_qz_x = 0; // qj wrt q1 + } - std::pair operations - = get_info_e::operations_of_equal(side_pi_y, side_pi_x, side_qz_x); + std::pair operations + = get_info_e::operations_of_equal(side_pi_y, side_pi_x, side_qz_x); - tp.operations[0].operation = operations.first; - tp.operations[1].operation = operations.second; + tp.operations[0].operation = operations.first; + tp.operations[1].operation = operations.second; - turn_transformer_ec transformer(method_none); - transformer(tp); + turn_transformer_ec transformer(method_none); + transformer(tp); - tp.operations[0].is_collinear = tp.both(operation_continue); - } + tp.operations[0].is_collinear = tp.both(operation_continue); + } - tp.method = ( ip_count > 1 ? ip1.is_qj : ip0.is_qj ) ? method_touch : method_touch_interior; - tp.operations[0].operation = operation_blocked; - tp.operations[0].position = position_back; - tp.operations[1].position = position_middle; + tp.method = ( ip_count > 1 ? ip1.is_qj : ip0.is_qj ) ? method_touch : method_touch_interior; + tp.operations[0].operation = operation_blocked; + tp.operations[0].position = position_back; + tp.operations[1].position = position_middle; - // equals<> or collinear<> will assign the second point, - // we'd like to assign the first one - unsigned int ip_index = ip_count > 1 ? 1 : 0; - base_turn_handler::assign_point(tp, tp.method, inters.i_info(), ip_index); + // equals<> or collinear<> will assign the second point, + // we'd like to assign the first one + unsigned int ip_index = ip_count > 1 ? 1 : 0; + base_turn_handler::assign_point(tp, tp.method, inters.i_info(), ip_index); - *out++ = tp; + *out++ = tp; - // don't ignore the first IP if the segment is opposite - return !( opposite && ip_count > 1 ) || was_first_point_handled; + // don't ignore the first IP if the segment is opposite + return !( opposite && ip_count > 1 ) || was_first_point_handled; + } } // don't ignore anything for now diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp index 6dbd6d682c..d0d1dfe5c6 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp @@ -1,11 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. // Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. - // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -22,7 +21,7 @@ #include #include -#include +#include namespace boost { namespace geometry { @@ -264,8 +263,11 @@ struct get_turn_info_linear_linear tp.operations[0].operation, tp.operations[1].operation); - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ! append_opposite_spikes(tp, inters, out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (! append_opposite_spikes(tp, inters, out)) { *out++ = tp; } @@ -307,10 +309,12 @@ struct get_turn_info_linear_linear transformer(tp); // conditionally handle spikes - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ! append_collinear_spikes(tp, inters, - method_touch, spike_op, - out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (! append_collinear_spikes(tp, inters, method_touch, + spike_op, out)) { *out++ = tp; // no spikes } @@ -381,10 +385,12 @@ struct get_turn_info_linear_linear transformer(tp); // conditionally handle spikes - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ! append_collinear_spikes(tp, inters, - method_replace, spike_op, - out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (! append_collinear_spikes(tp, inters, method_replace, + spike_op, out)) { // no spikes *out++ = tp; @@ -396,7 +402,7 @@ struct get_turn_info_linear_linear turn_transformer_ec transformer(method_touch_interior); // conditionally handle spikes - if ( BOOST_GEOMETRY_CONDITION(handle_spikes) ) + if BOOST_GEOMETRY_CONSTEXPR (handle_spikes) { append_opposite_spikes(tp, inters, out); } @@ -419,7 +425,7 @@ struct get_turn_info_linear_linear case '0' : { // degenerate points - if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) ) + if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_degenerate) { only_convert::apply(tp, inters.i_info()); @@ -553,65 +559,75 @@ struct get_turn_info_linear_linear bool res = false; - if ( is_p_spike - && ( BOOST_GEOMETRY_CONDITION(is_version_touches) - || inters.d_info().arrival[0] == 1 ) ) + if (is_p_spike) { - if ( BOOST_GEOMETRY_CONDITION(is_version_touches) ) + bool output_spike = false; + if BOOST_GEOMETRY_CONSTEXPR (is_version_touches) { tp.operations[0].is_collinear = true; tp.operations[1].is_collinear = false; tp.method = method_touch; + + output_spike = true; } - else // Version == append_collinear_opposite + else if (inters.d_info().arrival[0] == 1) // Version == append_collinear_opposite { tp.operations[0].is_collinear = true; tp.operations[1].is_collinear = false; BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1); - base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1); + + output_spike = true; } - tp.operations[0].operation = operation_blocked; - tp.operations[1].operation = operation_intersection; - *out++ = tp; - tp.operations[0].operation = operation_intersection; - //tp.operations[1].operation = operation_intersection; - *out++ = tp; + if (output_spike) + { + tp.operations[0].operation = operation_blocked; + tp.operations[1].operation = operation_intersection; + *out++ = tp; + tp.operations[0].operation = operation_intersection; + //tp.operations[1].operation = operation_intersection; + *out++ = tp; - res = true; + res = true; + } } - if ( is_q_spike - && ( BOOST_GEOMETRY_CONDITION(is_version_touches) - || inters.d_info().arrival[1] == 1 ) ) + if (is_q_spike) { - if ( BOOST_GEOMETRY_CONDITION(is_version_touches) ) + bool output_spike = false; + if BOOST_GEOMETRY_CONSTEXPR (is_version_touches) { tp.operations[0].is_collinear = false; tp.operations[1].is_collinear = true; tp.method = method_touch; + + output_spike = true; } - else // Version == append_collinear_opposite + else if (inters.d_info().arrival[1] == 1) // Version == append_collinear_opposite { tp.operations[0].is_collinear = false; tp.operations[1].is_collinear = true; BOOST_GEOMETRY_ASSERT(inters.i_info().count > 0); - base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 0); + + output_spike = true; } - tp.operations[0].operation = operation_intersection; - tp.operations[1].operation = operation_blocked; - *out++ = tp; - //tp.operations[0].operation = operation_intersection; - tp.operations[1].operation = operation_intersection; - *out++ = tp; + if (output_spike) + { + tp.operations[0].operation = operation_intersection; + tp.operations[1].operation = operation_blocked; + *out++ = tp; + //tp.operations[0].operation = operation_intersection; + tp.operations[1].operation = operation_intersection; + *out++ = tp; - res = true; + res = true; + } } return res; diff --git a/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp b/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp index bb1618ab3e..41dc46a335 100644 --- a/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp @@ -1,11 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2017-2020. // Modifications copyright (c) 2017-2020 Oracle and/or its affiliates. - // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -37,7 +36,7 @@ #include #include #include -#include +#include #if defined(BOOST_GEOMETRY_DEBUG_HANDLE_COLOCATIONS) # include @@ -339,7 +338,7 @@ inline bool handle_colocations(Turns& turns, Clusters& clusters, // on turns which are discarded afterwards set_colocation(turns, clusters); - if (BOOST_GEOMETRY_CONDITION(target_operation == operation_intersection)) + if BOOST_GEOMETRY_CONSTEXPR (target_operation == operation_intersection) { discard_interior_exterior_turns < @@ -495,11 +494,13 @@ inline void gather_cluster_properties(Clusters& clusters, Turns& turns, continue; } - if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_difference) - && is_self_turn(turn)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_difference) { - // TODO: investigate - continue; + if (is_self_turn(turn)) + { + // TODO: investigate + continue; + } } if ((for_operation == operation_union diff --git a/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp b/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp index 4ad311277a..388c965446 100644 --- a/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp @@ -36,7 +36,7 @@ #include -#include +#include namespace boost { namespace geometry @@ -261,13 +261,15 @@ struct multipoint_multipoint_point { typedef geometry::less less_type; - if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_difference) - && boost::size(multipoint1) > boost::size(multipoint2)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType != overlay_difference) { - return multipoint_multipoint_point - < - MultiPoint2, MultiPoint1, PointOut, OverlayType - >::apply(multipoint2, multipoint1, robust_policy, oit, strategy); + if (boost::size(multipoint1) > boost::size(multipoint2)) + { + return multipoint_multipoint_point + < + MultiPoint2, MultiPoint1, PointOut, OverlayType + >::apply(multipoint2, multipoint1, robust_policy, oit, strategy); + } } typedef typename boost::range_value::type point2_type; diff --git a/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp b/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp index dddb810a08..14f32beeda 100644 --- a/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2017-2023. // Modifications copyright (c) 2017-2023 Oracle and/or its affiliates. @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include @@ -459,7 +459,7 @@ public : void find_open() { - if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer) { find_open_by_piece_index(); } diff --git a/include/boost/geometry/algorithms/detail/overlay/traversal.hpp b/include/boost/geometry/algorithms/detail/overlay/traversal.hpp index b5a5d2eae4..4987f2c509 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal.hpp @@ -1,10 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2017-2020. // Modifications copyright (c) 2017-2020 Oracle and/or its affiliates. - // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -27,7 +27,7 @@ #include #include #include -#include +#include #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) \ || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT) \ @@ -233,23 +233,25 @@ public : { // For uu/ii, only switch sources if indicated - if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer) { // Buffer does not use source_index (always 0). return select_source_generic<&segment_identifier::multi_index>( turn, candidate_seg_id, previous_seg_id); } - - if (is_self_turn(turn)) + else // else prevents unreachable code warning { - // Also, if it is a self-turn, stay on same ring (multi/ring) - return select_source_generic<&segment_identifier::multi_index>( + if (is_self_turn(turn)) + { + // Also, if it is a self-turn, stay on same ring (multi/ring) + return select_source_generic<&segment_identifier::multi_index>( + turn, candidate_seg_id, previous_seg_id); + } + + // Use source_index + return select_source_generic<&segment_identifier::source_index>( turn, candidate_seg_id, previous_seg_id); } - - // Use source_index - return select_source_generic<&segment_identifier::source_index>( - turn, candidate_seg_id, previous_seg_id); } inline bool traverse_possible(signed_size_type turn_index) const @@ -342,25 +344,27 @@ public : return true; } - if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer) - && possible[0] && possible[1]) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer) { - // Buffers sometimes have multiple overlapping pieces, where remaining - // distance could lead to the wrong choice. Take the matching operation. - - bool is_target[2] = {0}; - for (int i = 0; i < 2; i++) + if (possible[0] && possible[1]) { - turn_operation_type const& next_op = m_turns[next[i]].operations[i]; - is_target[i] = next_op.operation == target_operation; - } + // Buffers sometimes have multiple overlapping pieces, where remaining + // distance could lead to the wrong choice. Take the matching operation. - if (is_target[0] != is_target[1]) - { - // Take the matching operation - selected_op_index = is_target[0] ? 0 : 1; - debug_traverse(turn, turn.operations[selected_op_index], "Candidate cc target"); - return true; + bool is_target[2] = {0}; + for (int i = 0; i < 2; i++) + { + turn_operation_type const& next_op = m_turns[next[i]].operations[i]; + is_target[i] = next_op.operation == target_operation; + } + + if (is_target[0] != is_target[1]) + { + // Take the matching operation + selected_op_index = is_target[0] ? 0 : 1; + debug_traverse(turn, turn.operations[selected_op_index], "Candidate cc target"); + return true; + } } } @@ -517,7 +521,7 @@ public : result = select_cc_operation(turn, start_turn_index, selected_op_index); } - else if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_dissolve)) + else if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_dissolve) { result = select_preferred_operation(turn, turn_index, start_turn_index, selected_op_index); @@ -584,12 +588,14 @@ public : return 0; } - if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_dissolve) - && (op.enriched.count_left != 0 || op.enriched.count_right == 0)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType != overlay_dissolve) { - // Check counts: in some cases interior rings might be generated with - // polygons on both sides. For dissolve it can be anything. - return 0; + if (op.enriched.count_left != 0 || op.enriched.count_right == 0) + { + // Check counts: in some cases interior rings might be generated with + // polygons on both sides. For dissolve it can be anything. + return 0; + } } bool const to_start = ranked_point.turn_index == start_turn_index; @@ -852,56 +858,58 @@ public : turn_operation_type const& start_op, int start_op_index) const { - if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_buffer - && OverlayType != overlay_dissolve)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType != overlay_buffer + && OverlayType != overlay_dissolve) { return; } - - const bool allow_uu = OverlayType != overlay_buffer; - - // It travels to itself, can happen. If this is a buffer, it can - // sometimes travel to itself in the following configuration: - // - // +---->--+ - // | | - // | +---*----+ *: one turn, with segment index 2/7 - // | | | | - // | +---C | C: closing point (start/end) - // | | - // +------------+ - // - // If it starts on segment 2 and travels to itself on segment 2, that - // should be corrected to 7 because that is the shortest path - // - // Also a uu turn (touching with another buffered ring) might have this - // apparent configuration, but there it should - // always travel the whole ring - - turn_operation_type const& other_op - = start_turn.operations[1 - start_op_index]; - - bool const correct - = (allow_uu || ! start_turn.both(operation_union)) - && start_op.seg_id.source_index == other_op.seg_id.source_index - && start_op.seg_id.multi_index == other_op.seg_id.multi_index - && start_op.seg_id.ring_index == other_op.seg_id.ring_index - && start_op.seg_id.segment_index == to_vertex_index; + else // else prevents unreachable code warning + { + const bool allow_uu = OverlayType != overlay_buffer; + + // It travels to itself, can happen. If this is a buffer, it can + // sometimes travel to itself in the following configuration: + // + // +---->--+ + // | | + // | +---*----+ *: one turn, with segment index 2/7 + // | | | | + // | +---C | C: closing point (start/end) + // | | + // +------------+ + // + // If it starts on segment 2 and travels to itself on segment 2, that + // should be corrected to 7 because that is the shortest path + // + // Also a uu turn (touching with another buffered ring) might have this + // apparent configuration, but there it should + // always travel the whole ring + + turn_operation_type const& other_op + = start_turn.operations[1 - start_op_index]; + + bool const correct + = (allow_uu || ! start_turn.both(operation_union)) + && start_op.seg_id.source_index == other_op.seg_id.source_index + && start_op.seg_id.multi_index == other_op.seg_id.multi_index + && start_op.seg_id.ring_index == other_op.seg_id.ring_index + && start_op.seg_id.segment_index == to_vertex_index; #if defined(BOOST_GEOMETRY_DEBUG_TRAVERSE) - std::cout << " WARNING: self-buffer " - << " correct=" << correct - << " turn=" << operation_char(start_turn.operations[0].operation) - << operation_char(start_turn.operations[1].operation) - << " start=" << start_op.seg_id.segment_index - << " from=" << to_vertex_index - << " to=" << other_op.enriched.travels_to_vertex_index - << std::endl; + std::cout << " WARNING: self-buffer " + << " correct=" << correct + << " turn=" << operation_char(start_turn.operations[0].operation) + << operation_char(start_turn.operations[1].operation) + << " start=" << start_op.seg_id.segment_index + << " from=" << to_vertex_index + << " to=" << other_op.enriched.travels_to_vertex_index + << std::endl; #endif - if (correct) - { - to_vertex_index = other_op.enriched.travels_to_vertex_index; + if (correct) + { + to_vertex_index = other_op.enriched.travels_to_vertex_index; + } } } @@ -960,7 +968,7 @@ public : = has_points && current_turn.is_clustered() && m_turns[start_turn_index].cluster_id == current_turn.cluster_id; - if (BOOST_GEOMETRY_CONDITION(target_operation == operation_intersection)) + if BOOST_GEOMETRY_CONSTEXPR (target_operation == operation_intersection) { // Intersection or difference diff --git a/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp b/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp index 1858c9ec2a..6043442d70 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp @@ -1,10 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2015-2016 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2018-2020. // Modifications copyright (c) 2018-2020 Oracle and/or its affiliates. - // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -26,7 +26,7 @@ #include #endif -#include +#include #include #include @@ -525,19 +525,21 @@ struct traversal_switch_detector return ! uu_or_ii(turn); } - if (BOOST_GEOMETRY_CONDITION(target_operation == operation_union)) + if BOOST_GEOMETRY_CONSTEXPR (target_operation == operation_union) { // It is a cluster, check zones // (assigned by sort_by_side/handle colocations) of both operations return turn.operations[0].enriched.zone == turn.operations[1].enriched.zone; } - - // For an intersection, two regions connect if they are not ii - // (ii-regions are isolated) or, in some cases, not iu (for example - // when a multi-polygon is inside an interior ring and connecting it) - return ! (turn.both(operation_intersection) - || turn.combination(operation_intersection, operation_union)); + else // else prevents unreachable code warning + { + // For an intersection, two regions connect if they are not ii + // (ii-regions are isolated) or, in some cases, not iu (for example + // when a multi-polygon is inside an interior ring and connecting it) + return ! (turn.both(operation_intersection) + || turn.combination(operation_intersection, operation_union)); + } } void create_region(signed_size_type& new_region_id, ring_identifier const& ring_id, @@ -682,11 +684,13 @@ struct traversal_switch_detector { turn_type const& turn = m_turns[turn_index]; - if (turn.discarded - && BOOST_GEOMETRY_CONDITION(target_operation == operation_intersection)) + if BOOST_GEOMETRY_CONSTEXPR (target_operation == operation_intersection) { - // Discarded turn (union currently still needs it to determine regions) - continue; + if (turn.discarded) + { + // Discarded turn (union currently still needs it to determine regions) + continue; + } } for (auto const& op : turn.operations) diff --git a/include/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp b/include/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp index e5ba6e30d8..9d2a6b7f52 100644 --- a/include/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp +++ b/include/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp @@ -3,11 +3,10 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2013-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2015, 2017, 2019. // Modifications copyright (c) 2015-2019 Oracle and/or its affiliates. - // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -23,7 +22,7 @@ #include #include #include -#include +#include #include @@ -85,30 +84,27 @@ inline bool point_is_spike_or_equal(Point1 const& last_point, return true; } - if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled)) + if BOOST_GEOMETRY_CONSTEXPR (! RobustPolicy::enabled) { return false; } - - // Try using specified robust policy - typedef typename geometry::robust_point_type - < - Point1, - RobustPolicy - >::type robust_point_type; - - robust_point_type last_point_rob, segment_a_rob, segment_b_rob; - geometry::recalculate(last_point_rob, last_point, robust_policy); - geometry::recalculate(segment_a_rob, segment_a, robust_policy); - geometry::recalculate(segment_b_rob, segment_b, robust_policy); - - return point_is_spike_or_equal - ( - last_point_rob, - segment_a_rob, - segment_b_rob, - strategy - ); + else // else prevents unreachable code warning + { + // Try using specified robust policy + using robust_point_type = typename geometry::robust_point_type + < + Point1, + RobustPolicy + >::type; + + robust_point_type last_point_rob, segment_a_rob, segment_b_rob; + geometry::recalculate(last_point_rob, last_point, robust_policy); + geometry::recalculate(segment_a_rob, segment_a, robust_policy); + geometry::recalculate(segment_b_rob, segment_b, robust_policy); + + return point_is_spike_or_equal(last_point_rob, segment_a_rob, segment_b_rob, + strategy); + } } template @@ -133,25 +129,27 @@ inline bool point_is_collinear(Point1 const& last_point, // This part (or whole method, because it is then trivial) // will be removed after rescaling - if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled)) + if BOOST_GEOMETRY_CONSTEXPR (! RobustPolicy::enabled) { return false; } - - // Redo, using specified robust policy - typedef typename geometry::robust_point_type - < - Point1, - RobustPolicy - >::type robust_point_type; - - robust_point_type last_point_rob, segment_a_rob, segment_b_rob; - geometry::recalculate(last_point_rob, last_point, robust_policy); - geometry::recalculate(segment_a_rob, segment_a, robust_policy); - geometry::recalculate(segment_b_rob, segment_b, robust_policy); - - int const side_rob = strategy.apply(segment_a_rob, segment_b_rob, last_point_rob); - return side_rob == 0; + else // else prevents unreachable code warning + { + // Redo, using specified robust policy + using robust_point_type = typename geometry::robust_point_type + < + Point1, + RobustPolicy + >::type; + + robust_point_type last_point_rob, segment_a_rob, segment_b_rob; + geometry::recalculate(last_point_rob, last_point, robust_policy); + geometry::recalculate(segment_a_rob, segment_a, robust_policy); + geometry::recalculate(segment_b_rob, segment_b, robust_policy); + + int const side_rob = strategy.apply(segment_a_rob, segment_b_rob, last_point_rob); + return side_rob == 0; + } } diff --git a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp index 1e35e64fc5..1dfea74903 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp @@ -17,25 +17,20 @@ #include #include -#include -#include - -#include -#include -#include - -#include #include -#include -#include - -#include -#include #include #include - +#include +#include +#include +#include +#include +#include +#include #include - +#include +#include +#include #include namespace boost { namespace geometry @@ -854,30 +849,30 @@ struct linear_areal m_exit_watcher.reset_detected_exit(); } - if ( BOOST_GEOMETRY_CONDITION( util::is_multi::value ) - && m_first_from_unknown ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) { - // For MultiPolygon many x/u operations may be generated as a first IP - // if for all turns x/u was generated and any of the Polygons doesn't contain the LineString - // then we know that the LineString is outside - // Similar with the u/u turns, if it was the first one it doesn't mean that the - // Linestring came from the exterior - if ( ( m_previous_operation == overlay::operation_blocked - && ( op != overlay::operation_blocked // operation different than block - || seg_id.multi_index != m_previous_turn_ptr->operations[op_id].seg_id.multi_index ) ) // or the next single-geometry - || ( m_previous_operation == overlay::operation_union - && ! turn_on_the_same_ip(*m_previous_turn_ptr, *it, - strategy) ) - ) + if (m_first_from_unknown) { - update(res); - if ( m_first_from_unknown_boundary_detected ) + // For MultiPolygon many x/u operations may be generated as a first IP + // if for all turns x/u was generated and any of the Polygons doesn't contain the LineString + // then we know that the LineString is outside + // Similar with the u/u turns, if it was the first one it doesn't mean that the + // Linestring came from the exterior + if ((m_previous_operation == overlay::operation_blocked + && (op != overlay::operation_blocked // operation different than block + || seg_id.multi_index != m_previous_turn_ptr->operations[op_id].seg_id.multi_index)) // or the next single-geometry + || (m_previous_operation == overlay::operation_union + && ! turn_on_the_same_ip(*m_previous_turn_ptr, *it, strategy))) { - update(res); - } + update(res); + if ( m_first_from_unknown_boundary_detected ) + { + update(res); + } - m_first_from_unknown = false; - m_first_from_unknown_boundary_detected = false; + m_first_from_unknown = false; + m_first_from_unknown_boundary_detected = false; + } } } @@ -1037,7 +1032,7 @@ struct linear_areal } } - if ( BOOST_GEOMETRY_CONDITION( util::is_multi::value ) ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) { m_first_from_unknown = false; m_first_from_unknown_boundary_detected = false; @@ -1123,9 +1118,9 @@ struct linear_areal } else { - if ( BOOST_GEOMETRY_CONDITION( util::is_multi::value ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) /*&& ( op == overlay::operation_blocked - || op == overlay::operation_union )*/ ) // if we're here it's u or x + || op == overlay::operation_union )*/ // if we're here it's u or x { m_first_from_unknown = true; } @@ -1150,9 +1145,9 @@ struct linear_areal } else { - if ( BOOST_GEOMETRY_CONDITION( util::is_multi::value ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) /*&& ( op == overlay::operation_blocked - || op == overlay::operation_union )*/ ) // if we're here it's u or x + || op == overlay::operation_union )*/ // if we're here it's u or x { BOOST_GEOMETRY_ASSERT(m_first_from_unknown); m_first_from_unknown_boundary_detected = true; @@ -1200,18 +1195,20 @@ struct linear_areal // For MultiPolygon many x/u operations may be generated as a first IP // if for all turns x/u was generated and any of the Polygons doesn't contain the LineString // then we know that the LineString is outside - if ( BOOST_GEOMETRY_CONDITION( util::is_multi::value ) - && m_first_from_unknown ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) { - update(res); - if ( m_first_from_unknown_boundary_detected ) + if (m_first_from_unknown) { - update(res); - } + update(res); + if ( m_first_from_unknown_boundary_detected ) + { + update(res); + } - // done below - //m_first_from_unknown = false; - //m_first_from_unknown_boundary_detected = false; + // done below + //m_first_from_unknown = false; + //m_first_from_unknown_boundary_detected = false; + } } // here, the possible exit is the real one diff --git a/include/boost/geometry/algorithms/detail/relate/point_point.hpp b/include/boost/geometry/algorithms/detail/relate/point_point.hpp index 9e8ccaca23..d83bc09897 100644 --- a/include/boost/geometry/algorithms/detail/relate/point_point.hpp +++ b/include/boost/geometry/algorithms/detail/relate/point_point.hpp @@ -69,7 +69,7 @@ std::pair point_multipoint_check(Point const& point, // point_in_geometry could be used here but why iterate over MultiPoint twice? // we must search for a point in the exterior because all points in MultiPoint can be equal - + auto const end = boost::end(multi_point); for (auto it = boost::begin(multi_point); it != end; ++it) { @@ -197,10 +197,12 @@ struct multipoint_multipoint || relate::may_update(result) ) { // NlogN + MlogN - bool is_disjoint = search(first_sorted_mpt, first_iterated_mpt, result); + bool const is_disjoint = search(first_sorted_mpt, first_iterated_mpt, result); - if ( BOOST_GEOMETRY_CONDITION(is_disjoint || result.interrupt) ) + if (is_disjoint || BOOST_GEOMETRY_CONDITION(result.interrupt) ) + { return; + } } if ( relate::may_update(result) diff --git a/include/boost/geometry/algorithms/detail/relate/result.hpp b/include/boost/geometry/algorithms/detail/relate/result.hpp index 84c342e636..de982c37a8 100644 --- a/include/boost/geometry/algorithms/detail/relate/result.hpp +++ b/include/boost/geometry/algorithms/detail/relate/result.hpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include namespace boost { namespace geometry { @@ -292,15 +292,18 @@ struct interrupt_dispatch template static inline bool check_element(char m) { - if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') ) + if BOOST_GEOMETRY_CONSTEXPR (V >= '0' && V <= '9') { return m == 'F' || ( m < V && m >= '0' && m <= '9' ); } - else if ( BOOST_GEOMETRY_CONDITION(V == 'T') ) + else if BOOST_GEOMETRY_CONSTEXPR (V == 'T') { return m == 'F'; } - return false; + else + { + return false; + } } }; diff --git a/include/boost/geometry/algorithms/detail/within/multi_point.hpp b/include/boost/geometry/algorithms/detail/within/multi_point.hpp index be984e9364..559d89d028 100644 --- a/include/boost/geometry/algorithms/detail/within/multi_point.hpp +++ b/include/boost/geometry/algorithms/detail/within/multi_point.hpp @@ -42,7 +42,7 @@ #include #include -#include +#include #include @@ -238,9 +238,16 @@ struct multi_point_multi_geometry if (boundaries > 0) { - if (BOOST_GEOMETRY_CONDITION(is_linear) && boundaries % 2 == 0) + if BOOST_GEOMETRY_CONSTEXPR (is_linear) { - found_interior = true; + if (boundaries % 2 == 0) + { + found_interior = true; + } + else + { + found_boundary = true; + } } else { diff --git a/include/boost/geometry/algorithms/line_interpolate.hpp b/include/boost/geometry/algorithms/line_interpolate.hpp index 5739c444ee..00e847d36c 100644 --- a/include/boost/geometry/algorithms/line_interpolate.hpp +++ b/include/boost/geometry/algorithms/line_interpolate.hpp @@ -1,5 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. + // Copyright (c) 2018-2023 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -35,7 +37,7 @@ #include #include -#include +#include #include #include @@ -133,13 +135,12 @@ struct interpolate_range p, diff_distance); Policy::apply(p, pointlike); - if ( BOOST_GEOMETRY_CONDITION(util::is_point::value) ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) { - return; + start_p = p; + prev_distance = repeated_distance; + repeated_distance += max_distance; } - start_p = p; - prev_distance = repeated_distance; - repeated_distance += max_distance; } prev_distance = current_distance; prev = it; diff --git a/include/boost/geometry/algorithms/remove_spikes.hpp b/include/boost/geometry/algorithms/remove_spikes.hpp index 7a144db154..9d50c60fcd 100644 --- a/include/boost/geometry/algorithms/remove_spikes.hpp +++ b/include/boost/geometry/algorithms/remove_spikes.hpp @@ -3,7 +3,7 @@ // Copyright (c) 2007-2013 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2013 Bruno Lalande, Paris, France. // Copyright (c) 2009-2013 Mateusz Loskot, London, UK. -// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2013-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2017-2023. // Modifications copyright (c) 2017-2023 Oracle and/or its affiliates. @@ -37,7 +37,7 @@ #include -#include +#include #include @@ -104,7 +104,7 @@ struct range_remove_spikes std::size_t cleaned_count = cleaned.size(); // For a closed-polygon, remove closing point, this makes checking first point(s) easier and consistent - if ( BOOST_GEOMETRY_CONDITION(geometry::closure::value == geometry::closed) ) + if BOOST_GEOMETRY_CONSTEXPR (geometry::closure::value == geometry::closed) { --cleaned_e; --cleaned_count; @@ -148,7 +148,7 @@ struct range_remove_spikes } // Close if necessary - if ( BOOST_GEOMETRY_CONDITION(geometry::closure::value == geometry::closed) ) + if BOOST_GEOMETRY_CONSTEXPR (geometry::closure::value == geometry::closed) { BOOST_GEOMETRY_ASSERT(cleaned_e != cleaned.end()); *cleaned_e = *cleaned_b; diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index 40c66e91a8..624d01334f 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -3,7 +3,7 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2018-2023. // Modifications copyright (c) 2018-2023 Oracle and/or its affiliates. @@ -61,6 +61,7 @@ #include #include +#include #include #ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER @@ -429,10 +430,10 @@ public : return; } - bool const is_closed_in = geometry::closure::value == closed; - bool const is_closed_out = geometry::closure::value == closed; - bool const is_clockwise_in = geometry::point_order::value == clockwise; - bool const is_clockwise_out = geometry::point_order::value == clockwise; + constexpr bool is_closed_in = geometry::closure::value == closed; + constexpr bool is_closed_out = geometry::closure::value == closed; + constexpr bool is_clockwise_in = geometry::point_order::value == clockwise; + constexpr bool is_clockwise_out = geometry::point_order::value == clockwise; // TODO: instead of area() use calculate_point_order() ? @@ -482,10 +483,13 @@ public : // Do not duplicate the closing point auto rot_end = boost::end(ring); std::size_t rot_index = index; - if (BOOST_GEOMETRY_CONDITION(is_closed_in) && size > 1) + if BOOST_GEOMETRY_CONSTEXPR (is_closed_in) { - --rot_end; - if (rot_index == size - 1) { rot_index = 0; } + if (size > 1) + { + --rot_end; + if (rot_index == size - 1) { rot_index = 0; } + } } std::rotate_copy(boost::begin(ring), range::pos(ring, rot_index), @@ -497,9 +501,12 @@ public : simplify_range<0>::apply(rotated, out, max_distance, impl, strategies); // Open output if needed - if (BOOST_GEOMETRY_CONDITION(! is_closed_out) && boost::size(out) > 1) + if BOOST_GEOMETRY_CONSTEXPR (! is_closed_out) { - range::pop_back(out); + if (boost::size(out) > 1) + { + range::pop_back(out); + } } // TODO: instead of area() use calculate_point_order() ? @@ -532,7 +539,7 @@ public : rotated.clear(); } - if (BOOST_GEOMETRY_CONDITION(is_clockwise_in != is_clockwise_out)) + if BOOST_GEOMETRY_CONSTEXPR (is_clockwise_in != is_clockwise_out) { std::reverse(boost::begin(out), boost::end(out)); } diff --git a/include/boost/geometry/formulas/andoyer_inverse.hpp b/include/boost/geometry/formulas/andoyer_inverse.hpp index 98f5dcd79e..708a574399 100644 --- a/include/boost/geometry/formulas/andoyer_inverse.hpp +++ b/include/boost/geometry/formulas/andoyer_inverse.hpp @@ -1,9 +1,8 @@ // Boost.Geometry -// Copyright (c) 2018 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2018-2023 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2015-2020 Oracle and/or its affiliates. - // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -18,7 +17,7 @@ #include -#include +#include #include #include @@ -98,7 +97,7 @@ class andoyer_inverse CT const d = acos(cos_d); // [0, pi] CT const sin_d = sin(d); // [-1, 1] - if ( BOOST_GEOMETRY_CONDITION(EnableDistance) ) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance) { CT const K = math::sqr(sin_lat1-sin_lat2); CT const L = math::sqr(sin_lat1+sin_lat2); @@ -123,7 +122,7 @@ class andoyer_inverse result.distance = a * (d + dd); } - if ( BOOST_GEOMETRY_CONDITION(CalcAzimuths) ) + if BOOST_GEOMETRY_CONSTEXPR (CalcAzimuths) { // sin_d = 0 <=> antipodal points (incl. poles) or very close if (math::equals(sin_d, c0)) @@ -210,14 +209,14 @@ class andoyer_inverse // therefore dA and dB may be great and the resulting azimuths // may be some more or less arbitrary angles - if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcFwdAzimuth) { CT const dA = V*T - U; result.azimuth = A - dA; normalize_azimuth(result.azimuth, A, dA); } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { CT const dB = -U*T + V; if (B >= 0) @@ -229,7 +228,7 @@ class andoyer_inverse } } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { CT const b = CT(get_radius<2>(spheroid)); diff --git a/include/boost/geometry/formulas/area_formulas.hpp b/include/boost/geometry/formulas/area_formulas.hpp index b8da8a6727..c45cd94f1f 100644 --- a/include/boost/geometry/formulas/area_formulas.hpp +++ b/include/boost/geometry/formulas/area_formulas.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2015-2022 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -381,26 +382,33 @@ class area_formulas return pi; } - if (BOOST_GEOMETRY_CONDITION(LongSegment) && lat1r != lat2r) // not for segments parallel to equator + if BOOST_GEOMETRY_CONSTEXPR (LongSegment) { - CT const cbet1 = cos(lat1r); - CT const sbet1 = sin(lat1r); - CT const cbet2 = cos(lat2r); - CT const sbet2 = sin(lat2r); - - CT const omg12 = lon2r - lon1r; - CT const comg12 = cos(omg12); - CT const somg12 = sin(omg12); - - CT const cbet1_sbet2 = cbet1 * sbet2; - CT const sbet1_cbet2 = sbet1 * cbet2; - CT const alp1 = atan2(cbet1_sbet2 - sbet1_cbet2 * comg12, cbet2 * somg12); - CT const alp2 = atan2(cbet1_sbet2 * comg12 - sbet1_cbet2, cbet1 * somg12); + if (lat1r != lat2r) // not for segments parallel to equator + { + CT const cbet1 = cos(lat1r); + CT const sbet1 = sin(lat1r); + CT const cbet2 = cos(lat2r); + CT const sbet2 = sin(lat2r); - excess = alp2 - alp1; + CT const omg12 = lon2r - lon1r; + CT const comg12 = cos(omg12); + CT const somg12 = sin(omg12); - } else { + CT const cbet1_sbet2 = cbet1 * sbet2; + CT const sbet1_cbet2 = sbet1 * cbet2; + CT const alp1 = atan2(cbet1_sbet2 - sbet1_cbet2 * comg12, cbet2 * somg12); + CT const alp2 = atan2(cbet1_sbet2 * comg12 - sbet1_cbet2, cbet1 * somg12); + excess = alp2 - alp1; + } + else + { + excess = trapezoidal_formula(lat1r, lat2r, lon12r); + } + } + else + { excess = trapezoidal_formula(lat1r, lat2r, lon12r); } diff --git a/include/boost/geometry/formulas/differential_quantities.hpp b/include/boost/geometry/formulas/differential_quantities.hpp index 1df9adb8e6..140a73867d 100644 --- a/include/boost/geometry/formulas/differential_quantities.hpp +++ b/include/boost/geometry/formulas/differential_quantities.hpp @@ -14,7 +14,7 @@ #include -#include +#include #include @@ -73,7 +73,7 @@ class differential_quantities if (math::equals(sin_bet1, c0) && math::equals(sin_bet2, c0)) { CT const sig_12 = dlon / one_minus_f; - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength) { BOOST_GEOMETRY_ASSERT((-math::pi() <= azimuth && azimuth <= math::pi())); @@ -82,7 +82,7 @@ class differential_quantities reduced_length = m12; } - if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale) { CT M12 = cos(sig_12); geodesic_scale = M12; @@ -123,7 +123,7 @@ class differential_quantities CT const dn1 = math::sqrt(c1 + ep2 * math::sqr(sin_bet1)); CT const dn2 = math::sqrt(c1 + ep2 * math::sqr(sin_bet2)); - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength) { CT const m12_b = dn2 * (cos_sig1 * sin_sig2) - dn1 * (sin_sig1 * cos_sig2) @@ -133,7 +133,7 @@ class differential_quantities reduced_length = m12; } - if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale) { CT const cos_sig12 = cos_sig1 * cos_sig2 + sin_sig1 * sin_sig2; CT const t = ep2 * (cos_bet1 - cos_bet2) * (cos_bet1 + cos_bet2) / (dn1 + dn2); diff --git a/include/boost/geometry/formulas/karney_direct.hpp b/include/boost/geometry/formulas/karney_direct.hpp index bfe35ddc49..ed365c8f1b 100644 --- a/include/boost/geometry/formulas/karney_direct.hpp +++ b/include/boost/geometry/formulas/karney_direct.hpp @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include #include @@ -162,7 +162,7 @@ class karney_direct CT const sin_sigma2 = sin_sigma1 * cos_sigma12 + cos_sigma1 * sin_sigma12; CT const cos_sigma2 = cos_sigma1 * cos_sigma12 - sin_sigma1 * sin_sigma12; - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { CT const sin_alpha2 = sin_alpha0; CT const cos_alpha2 = cos_alpha0 * cos_sigma2; @@ -170,7 +170,7 @@ class karney_direct result.reverse_azimuth = atan2(sin_alpha2, cos_alpha2); } - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { // Find the latitude at the second point. CT const sin_beta2 = cos_alpha0 * sin_sigma2; @@ -217,7 +217,7 @@ class karney_direct result.lon2 *= math::d2r(); } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { // Evaluate the coefficients for C2. // Index zero element of coeffs_C2 is unused. diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 12dd2b2598..cf338a5685 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include #include @@ -309,7 +309,7 @@ class karney_inverse sigma12 = omega12 = lam12 / one_minus_f; m12x = b * sin(sigma12); - if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale) { result.geodesic_scale = cos(sigma12); } @@ -335,7 +335,7 @@ class karney_inverse // Short lines case (newton_start sets sin_alpha2, cos_alpha2, dnm). s12x = sigma12 * b * dnm; m12x = math::sqr(dnm) * b * sin(sigma12 / dnm); - if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale) { result.geodesic_scale = cos(sigma12 / dnm); } @@ -460,25 +460,25 @@ class karney_inverse sin_alpha2 *= swap_point * lon12_sign; cos_alpha2 *= swap_point * lat_sign; - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength) { result.reduced_length = m12x; } - if (BOOST_GEOMETRY_CONDITION(CalcAzimuths)) + if BOOST_GEOMETRY_CONSTEXPR (CalcAzimuths) { - if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcFwdAzimuth) { result.azimuth = atan2(sin_alpha1, cos_alpha1); } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { result.reverse_azimuth = atan2(sin_alpha2, cos_alpha2); } } - if (BOOST_GEOMETRY_CONDITION(EnableDistance)) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance) { result.distance = s12x; } @@ -503,16 +503,13 @@ class karney_inverse // Evaluate the coefficients for C2. se::coeffs_C2 coeffs_C2(epsilon); - if (BOOST_GEOMETRY_CONDITION(EnableDistance) || - BOOST_GEOMETRY_CONDITION(EnableReducedLength) || - BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance || EnableReducedLength || EnableGeodesicScale) { // Find the coefficients for A1 by computing the // series expansion using Horner scehme. expansion_A1 = se::evaluate_A1(epsilon); - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || - BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength || EnableGeodesicScale) { // Find the coefficients for A2 by computing the // series expansion using Horner scehme. @@ -524,15 +521,14 @@ class karney_inverse expansion_A1 += c1; } - if (BOOST_GEOMETRY_CONDITION(EnableDistance)) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance) { CT B1 = se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C1) - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C1); s12x = expansion_A1 * (sigma12 + B1); - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || - BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength || EnableGeodesicScale) { CT B2 = se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C2) - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2); @@ -540,8 +536,7 @@ class karney_inverse J12 = A12x * sigma12 + (expansion_A1 * B1 - expansion_A2 * B2); } } - else if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || - BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + else if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength || EnableGeodesicScale) { for (size_t i = 1; i <= SeriesOrder; ++i) { @@ -554,7 +549,7 @@ class karney_inverse - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2)); } - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength) { m0 = A12x; @@ -563,7 +558,7 @@ class karney_inverse cos_sigma1 * cos_sigma2 * J12; } - if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale) { CT cos_sigma12 = cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2; CT t = ep2 * (cos_beta1 - cos_beta2) * diff --git a/include/boost/geometry/formulas/meridian_direct.hpp b/include/boost/geometry/formulas/meridian_direct.hpp index 3699e4c7cb..bbcb314fab 100644 --- a/include/boost/geometry/formulas/meridian_direct.hpp +++ b/include/boost/geometry/formulas/meridian_direct.hpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include namespace boost { namespace geometry { namespace formula @@ -66,7 +66,7 @@ class meridian_direct CT azimuth = north ? c0 : pi; - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { CT s0 = meridian_inverse::apply(la1, spheroid); int signed_distance = north ? distance : -distance; @@ -74,7 +74,7 @@ class meridian_direct result.lat2 = apply(s0 + signed_distance, spheroid); } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { result.reverse_azimuth = azimuth; @@ -92,7 +92,7 @@ class meridian_direct } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { CT const b = CT(get_radius<2>(spheroid)); CT const f = formula::flattening(spheroid); diff --git a/include/boost/geometry/formulas/thomas_direct.hpp b/include/boost/geometry/formulas/thomas_direct.hpp index 5889056671..c39c3751e4 100644 --- a/include/boost/geometry/formulas/thomas_direct.hpp +++ b/include/boost/geometry/formulas/thomas_direct.hpp @@ -1,7 +1,8 @@ // Boost.Geometry -// Copyright (c) 2016-2020 Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2016-2020 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -18,7 +19,7 @@ #include #include -#include +#include #include #include @@ -108,7 +109,7 @@ class thomas_direct CT const C2 = f * (c1 - math::sqr(M)) / c4; // lower-case c2 in the technical report CT D = 0; CT P = 0; - if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) + if BOOST_GEOMETRY_CONSTEXPR (SecondOrder) { D = (c1 - C2) * (c1 - C2 - C1 * M); P = C2 * (c1 + C1 * M / c2) / D; @@ -142,7 +143,7 @@ class thomas_direct CT const Y = c2 * P * V * W * sin_d; CT X = 0; CT d_sigma = d - Y; - if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) + if BOOST_GEOMETRY_CONSTEXPR (SecondOrder) { X = math::sqr(C2) * sin_d * cos_d * (2 * math::sqr(V) - c1); d_sigma += X; @@ -150,7 +151,7 @@ class thomas_direct CT const sin_d_sigma = sin(d_sigma); CT const cos_d_sigma = cos(d_sigma); - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { result.reverse_azimuth = atan2(M, N * cos_d_sigma - sin_theta1 * sin_d_sigma); @@ -160,12 +161,12 @@ class thomas_direct } } - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { CT const S_sigma = c2 * sigma1 - d_sigma; CT cos_S_sigma = 0; CT H = C1 * d_sigma; - if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) + if BOOST_GEOMETRY_CONSTEXPR (SecondOrder) { cos_S_sigma = cos(S_sigma); H = H * (c1 - C2) - C1 * C2 * sin_d_sigma * cos_S_sigma; @@ -196,7 +197,7 @@ class thomas_direct } } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { typedef differential_quantities quantities; quantities::apply(lon1, lat1, result.lon2, result.lat2, @@ -205,7 +206,7 @@ class thomas_direct result.reduced_length, result.geodesic_scale); } - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { // For longitudes close to the antimeridian the result can be out // of range. Therefore normalize. diff --git a/include/boost/geometry/formulas/thomas_inverse.hpp b/include/boost/geometry/formulas/thomas_inverse.hpp index c93aaf838c..5a6236d5d4 100644 --- a/include/boost/geometry/formulas/thomas_inverse.hpp +++ b/include/boost/geometry/formulas/thomas_inverse.hpp @@ -1,7 +1,8 @@ // Boost.Geometry -// Copyright (c) 2015-2018 Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2015-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -17,7 +18,7 @@ #include -#include +#include #include #include @@ -137,7 +138,7 @@ class thomas_inverse CT const f_sqr = math::sqr(f); CT const f_sqr_per_64 = f_sqr / CT(64); - if ( BOOST_GEOMETRY_CONDITION(EnableDistance) ) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance) { CT const n1 = X * (A + C*X); CT const n2 = Y * (B + E*Y); @@ -152,7 +153,7 @@ class thomas_inverse result.distance = a * sin_d * (T - delta1d + delta2d); } - if ( BOOST_GEOMETRY_CONDITION(CalcAzimuths) ) + if BOOST_GEOMETRY_CONSTEXPR (CalcAzimuths) { // NOTE: if both cos_latX == 0 then below we'd have 0 * INF // it's a situation when the endpoints are on the poles +-90 deg @@ -178,7 +179,7 @@ class thomas_inverse CT const pi = math::pi(); - if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcFwdAzimuth) { CT alpha1 = v + u; if (alpha1 > pi) @@ -189,7 +190,7 @@ class thomas_inverse result.azimuth = alpha1; } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { CT alpha2 = pi - (v - u); if (alpha2 > pi) @@ -201,7 +202,7 @@ class thomas_inverse } } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { typedef differential_quantities quantities; quantities::apply(lon1, lat1, lon2, lat2, diff --git a/include/boost/geometry/formulas/vincenty_direct.hpp b/include/boost/geometry/formulas/vincenty_direct.hpp index 274af3f2f2..2692266a67 100644 --- a/include/boost/geometry/formulas/vincenty_direct.hpp +++ b/include/boost/geometry/formulas/vincenty_direct.hpp @@ -1,10 +1,10 @@ // Boost.Geometry // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2014-2020. // Modifications copyright (c) 2014-2020 Oracle and/or its affiliates. - // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -19,7 +19,7 @@ #include -#include +#include #include #include @@ -136,7 +136,7 @@ class vincenty_direct //&& geometry::math::abs(sigma) < pi && counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { result.lat2 = atan2( sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_azimuth12, @@ -151,13 +151,13 @@ class vincenty_direct result.lon2 = lon1 + L; } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { result.reverse_azimuth = atan2(sin_alpha, -sin_U1 * sin_sigma + cos_U1 * cos_sigma * cos_azimuth12); // (12) } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { typedef differential_quantities quantities; quantities::apply(lon1, lat1, result.lon2, result.lat2, @@ -166,7 +166,7 @@ class vincenty_direct result.reduced_length, result.geodesic_scale); } - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { // For longitudes close to the antimeridian the result can be out // of range. Therefore normalize. diff --git a/include/boost/geometry/formulas/vincenty_inverse.hpp b/include/boost/geometry/formulas/vincenty_inverse.hpp index 24f285d9bc..7789e17e97 100644 --- a/include/boost/geometry/formulas/vincenty_inverse.hpp +++ b/include/boost/geometry/formulas/vincenty_inverse.hpp @@ -1,11 +1,10 @@ // Boost.Geometry // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2018 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2018-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2014, 2016, 2017. // Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. - // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -20,7 +19,7 @@ #include -#include +#include #include #include @@ -160,7 +159,7 @@ struct vincenty_inverse && geometry::math::abs(lambda) < pi && counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness - if ( BOOST_GEOMETRY_CONDITION(EnableDistance) ) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance) { // Some types cannot divide by doubles CT const c6 = 6; @@ -188,20 +187,20 @@ struct vincenty_inverse result.distance = radius_b * A * (sigma - delta_sigma); // (19) } - if ( BOOST_GEOMETRY_CONDITION(CalcAzimuths) ) + if BOOST_GEOMETRY_CONSTEXPR (CalcAzimuths) { - if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcFwdAzimuth) { result.azimuth = atan2(cos_U2 * sin_lambda, cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda); // (20) } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { result.reverse_azimuth = atan2(cos_U1 * sin_lambda, -sin_U1 * cos_U2 + cos_U1 * sin_U2 * cos_lambda); // (21) } } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { typedef differential_quantities quantities; quantities::apply(lon1, lat1, lon2, lat2, diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index fba76efb1c..621b602c19 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -21,6 +21,8 @@ #include +#include + #include #include @@ -36,14 +38,14 @@ #include #include -#include - #include #include #include #include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { @@ -92,11 +94,10 @@ inline Box values_box(FwdIter first, FwdIter last, Translator const& tr, Box result = elements_box(first, last, tr, strategy); #ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON - if (BOOST_GEOMETRY_CONDITION(( - ! is_bounding_geometry - < - typename indexable_type::type - >::value))) + if BOOST_GEOMETRY_CONSTEXPR (! index::detail::is_bounding_geometry + < + typename indexable_type::type + >::value) { geometry::detail::expand_by_epsilon(result); } diff --git a/include/boost/geometry/index/detail/rtree/pack_create.hpp b/include/boost/geometry/index/detail/rtree/pack_create.hpp index 33600a4c93..dab7cfdbdd 100644 --- a/include/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/include/boost/geometry/index/detail/rtree/pack_create.hpp @@ -31,6 +31,8 @@ #include #include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace pack_utils { @@ -343,11 +345,10 @@ class pack // NOTE: this is done only if the Indexable is a different kind of Geometry // than the bounds (only Box for now). Spatial predicates are checked // the same way for Geometry of the same kind. - if ( BOOST_GEOMETRY_CONDITION(( - ! index::detail::is_bounding_geometry - < - typename indexable_type::type - >::value )) ) + if BOOST_GEOMETRY_CONSTEXPR (! index::detail::is_bounding_geometry + < + typename indexable_type::type + >::value) { elements_box.expand_by_epsilon(); } diff --git a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp index 2d87e21a17..f6863a3516 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp @@ -30,7 +30,7 @@ #include #include -#include +#include namespace boost { namespace geometry { namespace index { @@ -328,12 +328,11 @@ class insert // Enlarge it in case if it's not bounding geometry type. // It's because Points and Segments are compared WRT machine epsilon // This ensures that leafs bounds correspond to the stored elements - if (BOOST_GEOMETRY_CONDITION(( - std::is_same::value - && ! index::detail::is_bounding_geometry - < - typename indexable_type::type - >::value )) ) + if BOOST_GEOMETRY_CONSTEXPR (std::is_same::value + && ! index::detail::is_bounding_geometry + < + typename indexable_type::type + >::value) { geometry::detail::expand_by_epsilon(m_element_bounds); } @@ -425,12 +424,11 @@ class insert // Enlarge bounds of a leaf node. // It's because Points and Segments are compared WRT machine epsilon // This ensures that leafs' bounds correspond to the stored elements. - if (BOOST_GEOMETRY_CONDITION(( - std::is_same::value - && ! index::detail::is_bounding_geometry - < - typename indexable_type::type - >::value ))) + if BOOST_GEOMETRY_CONSTEXPR (std::is_same::value + && ! index::detail::is_bounding_geometry + < + typename indexable_type::type + >::value) { geometry::detail::expand_by_epsilon(n_box); geometry::detail::expand_by_epsilon(additional_nodes[0].first); diff --git a/include/boost/geometry/policies/is_valid/failing_reason_policy.hpp b/include/boost/geometry/policies/is_valid/failing_reason_policy.hpp index 701e72c2d3..89292a47f7 100644 --- a/include/boost/geometry/policies/is_valid/failing_reason_policy.hpp +++ b/include/boost/geometry/policies/is_valid/failing_reason_policy.hpp @@ -181,12 +181,11 @@ class failing_reason_policy static inline void apply(std::ostringstream& oss, Point const& point) { - if BOOST_GEOMETRY_CONSTEXPR (AllowDuplicates) + if BOOST_GEOMETRY_CONSTEXPR (! AllowDuplicates) { - return; + oss << ". Duplicate points were found near point " + << geometry::dsv(point); } - oss << ". Duplicate points were found near point " - << geometry::dsv(point); } }; diff --git a/include/boost/geometry/srs/projections/impl/pj_transform.hpp b/include/boost/geometry/srs/projections/impl/pj_transform.hpp index b4f14c80b5..9f16c0e6f6 100644 --- a/include/boost/geometry/srs/projections/impl/pj_transform.hpp +++ b/include/boost/geometry/srs/projections/impl/pj_transform.hpp @@ -252,7 +252,7 @@ inline bool pj_transform(SrcPrj const& srcprj, Par const& srcdefn, /* -------------------------------------------------------------------- */ /* Transform Z to meters if it isn't already. */ /* -------------------------------------------------------------------- */ - if( BOOST_GEOMETRY_CONDITION(srcdefn.vto_meter != 1.0 && dimension > 2) ) + if( srcdefn.vto_meter != 1.0 && BOOST_GEOMETRY_CONDITION(dimension > 2) ) { for( std::size_t i = 0; i < point_count; i++ ) { @@ -589,7 +589,7 @@ inline bool pj_transform(SrcPrj const& srcprj, Par const& srcdefn, /* -------------------------------------------------------------------- */ /* Transform Z from meters if needed. */ /* -------------------------------------------------------------------- */ - if( dstdefn.vto_meter != 1.0 && dimension > 2 ) + if( dstdefn.vto_meter != 1.0 && BOOST_GEOMETRY_CONDITION(dimension > 2) ) { for( std::size_t i = 0; i < point_count; i++ ) { diff --git a/include/boost/geometry/strategies/spherical/point_order.hpp b/include/boost/geometry/strategies/spherical/point_order.hpp index 52450dc635..3f9eb8ce47 100644 --- a/include/boost/geometry/strategies/spherical/point_order.hpp +++ b/include/boost/geometry/strategies/spherical/point_order.hpp @@ -1,7 +1,8 @@ // Boost.Geometry -// Copyright (c) 2019-2020, Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2019-2020, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. @@ -100,7 +101,7 @@ namespace strategy { namespace point_order // spherical_polar_tag // >::value; // -// if (BOOST_GEOMETRY_CONDITION(is_polar)) +// if BOOST_GEOMETRY_CONSTEXPR (is_polar) // { // CalcT pi_half = math::half_pi(); // lat1 = pi_half - lat1; diff --git a/include/boost/geometry/util/precise_math.hpp b/include/boost/geometry/util/precise_math.hpp index fb1b078451..2d367e5527 100644 --- a/include/boost/geometry/util/precise_math.hpp +++ b/include/boost/geometry/util/precise_math.hpp @@ -328,7 +328,7 @@ inline RealNumber orient2dtail(vec2d const& p1, * std::numeric_limits::epsilon(); absolute_bound = C_relative_bound * magnitude + sub_bound * std::abs(det); det += (t1[0] * t2[1] + t2[0] * t1[1]) - (t3[0] * t4[1] + t4[0] * t3[1]); - if (Robustness == 2 || std::abs(det) >= absolute_bound) + if (BOOST_GEOMETRY_CONDITION(Robustness == 2) || std::abs(det) >= absolute_bound) { return det; //C estimate } @@ -457,7 +457,10 @@ RealNumber incircle(std::array const& p1, RealNumber det = A_13 * (A_21_x_A_32[0] - A_31_x_A_22[0]) + A_23 * (A_31_x_A_12[0] - A_11_x_A_32[0]) + A_33 * (A_11_x_A_22[0] - A_21_x_A_12[0]); - if(Robustness == 0) return det; + if (BOOST_GEOMETRY_CONDITION(Robustness == 0)) + { + return det; + } RealNumber magnitude = (std::abs(A_21_x_A_32[0]) + std::abs(A_31_x_A_22[0])) * A_13 @@ -585,7 +588,10 @@ RealNumber incircle(std::array const& p1, det = std::accumulate(det_expansion.begin(), det_expansion.begin() + det_expansion_nz, static_cast(0)); - if(Robustness == 1) return det; + if (BOOST_GEOMETRY_CONDITION(Robustness == 1)) + { + return det; + } RealNumber B_relative_bound = (2 + 12 * std::numeric_limits::epsilon()) * std::numeric_limits::epsilon();