From fb9b1d40ff853e4c88c0bdc6ba4facecd5ccdd2d Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Tue, 29 Jun 2021 13:20:07 +0300 Subject: [PATCH 01/74] Replace side_by_triangle with side_robust --- .../detail/equals/collect_vectors.hpp | 6 +- .../agnostic/point_in_box_by_side.hpp | 6 +- .../cartesian/distance_segment_box.hpp | 1 - .../strategies/cartesian/intersection.hpp | 4 +- .../cartesian/point_in_poly_winding.hpp | 4 +- .../geometry/strategies/relate/cartesian.hpp | 12 +- .../strategy/cartesian/side_non_robust.hpp | 1 + .../strategy/cartesian/side_robust.hpp | 119 +++++++++++++++--- include/boost/geometry/util/precise_math.hpp | 55 ++++++-- .../geometry/util/select_most_precise.hpp | 40 +++++- .../convex_hull/convex_hull_robust.cpp | 1 + .../convex_hull/test_convex_hull.hpp | 70 +++++++++-- .../overlay/get_turns_linear_linear.cpp | 13 +- .../sym_difference/sym_difference_tupled.cpp | 2 +- 14 files changed, 267 insertions(+), 67 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp b/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp index 35ec77a92..b435fff2f 100644 --- a/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp +++ b/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp @@ -40,7 +40,7 @@ #include -#include +#include #include #include @@ -62,11 +62,11 @@ struct collected_vector : nyi::not_implemented_tag {}; -// compatible with side_by_triangle cartesian strategy +// compatible with side_robust cartesian strategy template struct collected_vector < - T, Geometry, strategy::side::side_by_triangle, CSTag + T, Geometry, strategy::side::side_robust, CSTag > { typedef T type; diff --git a/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp b/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp index 5ea58736e..c794a3b23 100644 --- a/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp +++ b/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -118,7 +118,7 @@ struct cartesian_point_box_by_side < within::detail::decide_within >(point, box, - strategy::side::side_by_triangle()); + strategy::side::side_robust()); } }; @@ -189,7 +189,7 @@ struct cartesian_point_box_by_side < within::detail::decide_covered_by >(point, box, - strategy::side::side_by_triangle()); + strategy::side::side_robust()); } }; diff --git a/include/boost/geometry/strategies/cartesian/distance_segment_box.hpp b/include/boost/geometry/strategies/cartesian/distance_segment_box.hpp index c00e426a4..ab3aab726 100644 --- a/include/boost/geometry/strategies/cartesian/distance_segment_box.hpp +++ b/include/boost/geometry/strategies/cartesian/distance_segment_box.hpp @@ -17,7 +17,6 @@ #include #include #include -#include namespace boost { namespace geometry { diff --git a/include/boost/geometry/strategies/cartesian/intersection.hpp b/include/boost/geometry/strategies/cartesian/intersection.hpp index be7b92e59..cbf4aa486 100644 --- a/include/boost/geometry/strategies/cartesian/intersection.hpp +++ b/include/boost/geometry/strategies/cartesian/intersection.hpp @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include #include @@ -402,7 +402,7 @@ struct cartesian_segments return Policy::disjoint(); } - typedef side::side_by_triangle side_strategy_type; + typedef side::side_robust side_strategy_type; side_info sides; sides.set<0>(side_strategy_type::apply(q1, q2, p1), side_strategy_type::apply(q1, q2, p2)); diff --git a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp index b3556741c..3df4bcc44 100644 --- a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include @@ -116,7 +116,7 @@ public: else // count == 2 || count == -2 { // 1 left, -1 right - typedef side::side_by_triangle side_strategy_type; + typedef side::side_robust side_strategy_type; side = side_strategy_type::apply(s1, s2, point); } diff --git a/include/boost/geometry/strategies/relate/cartesian.hpp b/include/boost/geometry/strategies/relate/cartesian.hpp index 16c6853a3..5b418913d 100644 --- a/include/boost/geometry/strategies/relate/cartesian.hpp +++ b/include/boost/geometry/strategies/relate/cartesian.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -147,7 +148,7 @@ public: static auto side() { - return strategy::side::side_by_triangle(); + return strategy::side::side_robust(); } // within @@ -372,6 +373,15 @@ struct strategy_converter> } }; +template +struct strategy_converter> +{ + static auto get(strategy::side::side_robust const&) + { + return strategies::relate::cartesian(); + } +}; + } // namespace services diff --git a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp index 2ef109cc1..098cb9bd4 100644 --- a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp @@ -62,6 +62,7 @@ public: * (promoted_type(get<1>(p2)) - promoted_type(get<1>(p))); auto detright = (promoted_type(get<1>(p1)) - promoted_type(get<1>(p))) * (promoted_type(get<0>(p2)) - promoted_type(get<0>(p))); + return detleft > detright ? 1 : (detleft < detright ? -1 : 0 ); } diff --git a/include/boost/geometry/strategy/cartesian/side_robust.hpp b/include/boost/geometry/strategy/cartesian/side_robust.hpp index 4ee4a1726..9e69a0c80 100644 --- a/include/boost/geometry/strategy/cartesian/side_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_robust.hpp @@ -5,6 +5,11 @@ // Contributed and/or modified by Tinko Bartels, // as part of Google Summer of Code 2019 program. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -12,9 +17,16 @@ #ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP #define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP +#include + +#include + +#include + #include #include #include +#include namespace boost { namespace geometry { @@ -22,6 +34,28 @@ namespace boost { namespace geometry namespace strategy { namespace side { +struct eps_equals_policy +{ +public: + + template + static auto apply(T1 a, T2 b, Policy policy) + { + return boost::geometry::math::detail::equals_by_policy(a, b, policy); + } +}; + +struct fp_equals_policy +{ +public: + template + static auto apply(T1 a, T2 b, Policy) + { + return a == b; + } +}; + + /*! \brief Adaptive precision predicate to check at which side of a segment a point lies: left of segment (>0), right of segment (< 0), on segment (0). @@ -33,57 +67,106 @@ namespace strategy { namespace side template < typename CalculationType = void, + typename EpsPolicy = eps_equals_policy, std::size_t Robustness = 3 > struct side_robust { + template + struct eps_policy + { + eps_policy() {} + template + eps_policy(Type const& a, Type const& b, Type const& c, Type const& d) + : policy(a, b, c, d) + {} + Policy policy; + }; + public: - //! \brief Computes double the signed area of the CCW triangle p1, p2, p + + typedef cartesian_tag cs_tag; + + //! \brief Computes the sign of the CCW triangle p1, p2, p template < typename PromotedType, typename P1, typename P2, - typename P + typename P, + typename EpsPolicyInternal, + std::enable_if_t::value, int> = 0 > - static inline PromotedType side_value(P1 const& p1, P2 const& p2, - P const& p) + static inline PromotedType side_value(P1 const& p1, + P2 const& p2, + P const& p, + EpsPolicyInternal& eps_policy) { - typedef ::boost::geometry::detail::precise_math::vec2d vec2d; - vec2d pa { get<0>(p1), get<1>(p1) }; - vec2d pb { get<0>(p2), get<1>(p2) }; - vec2d pc { get<0>(p), get<1>(p) }; + using vec2d = ::boost::geometry::detail::precise_math::vec2d; + vec2d pa; + pa.x = get<0>(p1); + pa.y = get<1>(p1); + vec2d pb; + pb.x = get<0>(p2); + pb.y = get<1>(p2); + vec2d pc; + pc.x = get<0>(p); + pc.y = get<1>(p); return ::boost::geometry::detail::precise_math::orient2d - (pa, pb, pc); + (pa, pb, pc, eps_policy); + } + + template + < + typename PromotedType, + typename P1, + typename P2, + typename P, + typename EpsPolicyInternal, + std::enable_if_t::value, int> = 0 + > + static inline auto side_value(P1 const& p1, P2 const& p2, P const& p, + EpsPolicyInternal&) + { + return side_non_robust<>::apply(p1, p2, p); } #ifndef DOXYGEN_SHOULD_SKIP_THIS template - < + < typename P1, typename P2, typename P > static inline int apply(P1 const& p1, P2 const& p2, P const& p) { - typedef typename select_calculation_type_alt + using coordinate_type = typename select_calculation_type_alt < CalculationType, P1, P2, P - >::type coordinate_type; - typedef typename select_most_precise + >::type; + + using promoted_type = typename select_most_precise < coordinate_type, double - >::type promoted_type; + >::type; - promoted_type sv = side_value(p1, p2, p); - return sv > 0 ? 1 - : sv < 0 ? -1 - : 0; + eps_policy + < + boost::geometry::math::detail::equals_factor_policy + > epsp; + + promoted_type sv = side_value(p1, p2, p, epsp); + + promoted_type const zero = promoted_type(); + return EpsPolicy::apply(sv, zero, epsp.policy) ? 0 + : sv > zero ? 1 + : -1; } + #endif }; diff --git a/include/boost/geometry/util/precise_math.hpp b/include/boost/geometry/util/precise_math.hpp index c70762097..eccf08800 100644 --- a/include/boost/geometry/util/precise_math.hpp +++ b/include/boost/geometry/util/precise_math.hpp @@ -5,6 +5,10 @@ // Contributed and/or modified by Tinko Bartels, // as part of Google Summer of Code 2019 program. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -157,7 +161,9 @@ inline int fast_expansion_sum_zeroelim( int n = InSize2) { std::array Qh; - int i_e = 0, i_f = 0, i_h = 0; + int i_e = 0; + int i_f = 0; + int i_h = 0; if (std::abs(f[0]) > std::abs(e[0])) { Qh[0] = e[i_e++]; @@ -282,14 +288,16 @@ inline RealNumber orient2dtail(vec2d const& p1, std::array& t4, std::array& t5_01, std::array& t6_01, - RealNumber const& magnitude - ) + RealNumber const& magnitude) { t5_01[1] = two_product_tail(t1[0], t2[0], t5_01[0]); t6_01[1] = two_product_tail(t3[0], t4[0], t6_01[0]); std::array tA_03 = two_two_expansion_diff(t5_01, t6_01); RealNumber det = std::accumulate(tA_03.begin(), tA_03.end(), static_cast(0)); - if(Robustness == 1) return det; + if (Robustness == 1) + { + return det; + } // see p.39, mind the different definition of epsilon for error bound RealNumber B_relative_bound = (1 + 3 * std::numeric_limits::epsilon()) @@ -347,29 +355,51 @@ inline RealNumber orient2dtail(vec2d const& p1, return(D[D_nz - 1]); } -// see page 38, Figure 21 for the calculations, notation follows the notation in the figure. +// see page 38, Figure 21 for the calculations, notation follows the notation +// in the figure. template < typename RealNumber, - std::size_t Robustness = 3 + std::size_t Robustness = 3, + typename EpsPolicy > inline RealNumber orient2d(vec2d const& p1, vec2d const& p2, - vec2d const& p3) + vec2d const& p3, + EpsPolicy& eps_policy) { - if(Robustness == 0) - { - return (p1.x - p3.x) * (p2.y - p3.y) - (p1.y - p3.y) * (p2.x - p3.x); - } + auto const x = p3.x; + auto const y = p3.y; + + auto const sx1 = p1.x; + auto const sy1 = p1.y; + auto const sx2 = p2.x; + auto const sy2 = p2.y; + + + auto const dx = sx2 - sx1; + auto const dy = sy2 - sy1; + auto const dpx = x - sx1; + auto const dpy = y - sy1; + + eps_policy = EpsPolicy(dx, dy, dpx, dpy); + std::array t1, t2, t3, t4; t1[0] = p1.x - p3.x; t2[0] = p2.y - p3.y; t3[0] = p1.y - p3.y; t4[0] = p2.x - p3.x; + std::array t5_01, t6_01; t5_01[0] = t1[0] * t2[0]; t6_01[0] = t3[0] * t4[0]; RealNumber det = t5_01[0] - t6_01[0]; + + if (Robustness == 0) + { + return det; + } + RealNumber const magnitude = std::abs(t5_01[0]) + std::abs(t6_01[0]); // see p.39, mind the different definition of epsilon for error bound @@ -388,7 +418,8 @@ inline RealNumber orient2d(vec2d const& p1, //obvious return det; } - return orient2dtail(p1, p2, p3, t1, t2, t3, t4, t5_01, t6_01, magnitude); + return orient2dtail(p1, p2, p3, t1, t2, t3, t4, + t5_01, t6_01, magnitude); } // This method adaptively computes increasingly precise approximations of the following diff --git a/include/boost/geometry/util/select_most_precise.hpp b/include/boost/geometry/util/select_most_precise.hpp index d6c6337b4..3fb8d8a73 100644 --- a/include/boost/geometry/util/select_most_precise.hpp +++ b/include/boost/geometry/util/select_most_precise.hpp @@ -30,7 +30,6 @@ namespace boost { namespace geometry namespace detail { namespace select_most_precise { - // 0 - void // 1 - integral // 2 - floating point @@ -55,6 +54,43 @@ struct type_priority > {}; +/* +// 0 - void +// 1 - integral (int, long int) +// 2 - floating point (float, double) +// 3 - long long int +// 4 - long double +// 5 - non-fundamental +template +struct type_priority + : std::conditional_t + < + std::is_void::value, + std::integral_constant, + std::conditional_t + < + std::is_fundamental::value, + std::conditional_t + < + std::is_same::value, + std::integral_constant, + std::conditional_t + < + std::is_same::value, + std::integral_constant, + std::conditional_t + < + std::is_floating_point::value, + std::integral_constant, + std::integral_constant + > + > + >, + std::integral_constant + > + > +{}; +*/ template struct type_size @@ -119,7 +155,7 @@ struct select_most_precise T2, std::conditional_t // priority1 == priority2 < - (priority1 == 0 || priority1 == 3), // both void or non-fundamental + (priority1 == 0 || priority1 == 5), // both void or non-fundamental T1, std::conditional_t // both fundamental < diff --git a/test/algorithms/convex_hull/convex_hull_robust.cpp b/test/algorithms/convex_hull/convex_hull_robust.cpp index 9ee6e55f4..1a53321fd 100644 --- a/test/algorithms/convex_hull/convex_hull_robust.cpp +++ b/test/algorithms/convex_hull/convex_hull_robust.cpp @@ -82,6 +82,7 @@ void test_all() polygon_wkt3, 5, 4, 1.4210854715202004e-14); test_geometry, non_robust_cartesian_sbt >( polygon_wkt3, 5, 5, 1.69333333333333265e-13); + return ; // missing one point could lead in arbitrary large errors in area auto polygon_wkt4 = "polygon((0.10000000000000001 0.10000000000000001,\ diff --git a/test/algorithms/convex_hull/test_convex_hull.hpp b/test/algorithms/convex_hull/test_convex_hull.hpp index df1b959b0..c901e3c0b 100644 --- a/test/algorithms/convex_hull/test_convex_hull.hpp +++ b/test/algorithms/convex_hull/test_convex_hull.hpp @@ -3,9 +3,10 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014, 2015. -// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2015, 2021. +// Modifications copyright (c) 2014-2021 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 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -43,7 +44,11 @@ struct robust_cartesian : boost::geometry::strategies::detail::cartesian_base { static auto side() { - return boost::geometry::strategy::side::side_robust<>(); + return boost::geometry::strategy::side::side_robust + < + double, + boost::geometry::strategy::side::fp_equals_policy + >(); } }; @@ -159,15 +164,12 @@ struct test_convex_hull std::size_t size_hull_closed, double expected_area, double expected_perimeter, - bool reverse) + bool /*reverse*/) { - bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open; static bool const is_hull_closed = bg::closure::value != bg::open; // convex_hull_insert() uses the original Geometry as a source of the info // about the order and closure - std::size_t const size_hull_from_orig = is_original_closed ? - size_hull_closed : size_hull_closed - 1; std::size_t const size_hull = is_hull_closed ? size_hull_closed : size_hull_closed - 1; @@ -179,14 +181,19 @@ struct test_convex_hull check_convex_hull(geometry, hull, size_original, size_hull, expected_area, expected_perimeter, false, AreaStrategy()); - // Test version with output iterator and strategy + // Do not test with output iterator since it does not support + // non-default strategy + /* + bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open; + std::size_t const size_hull_from_orig = is_original_closed ? + size_hull_closed : size_hull_closed - 1; bg::clear(hull); bg::detail::convex_hull::convex_hull_insert( geometry, std::back_inserter(hull.outer()), Strategy()); check_convex_hull(geometry, hull, size_original, size_hull_from_orig, expected_area, expected_perimeter, reverse, AreaStrategy()); - + */ } }; @@ -254,6 +261,49 @@ struct test_convex_hull }; +template +< + typename Hull +> +struct test_convex_hull +{ + template + static void apply(Geometry const& geometry, + std::size_t size_original, + std::size_t size_hull_closed, + double expected_area, + double expected_perimeter, + bool reverse) + { + bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open; + static bool const is_hull_closed = bg::closure::value != bg::open; + + // convex_hull_insert() uses the original Geometry as a source of the info + // about the order and closure + std::size_t const size_hull_from_orig = is_original_closed ? + size_hull_closed : size_hull_closed - 1; + std::size_t const size_hull = is_hull_closed ? size_hull_closed : + size_hull_closed - 1; + + Hull hull; + + // Test version with strategy + bg::clear(hull); + bg::convex_hull(geometry, hull.outer(), robust_cartesian()); + check_convex_hull(geometry, hull, size_original, size_hull, expected_area, + expected_perimeter, false, precise_cartesian()); + + // Test version with output iterator and strategy + bg::clear(hull); + bg::detail::convex_hull::convex_hull_insert(geometry, + std::back_inserter(hull.outer()), robust_cartesian()); + check_convex_hull(geometry, hull, size_original, size_hull_from_orig, + expected_area, expected_perimeter, reverse, precise_cartesian()); + + } +}; + + template < typename Geometry, @@ -342,6 +392,4 @@ void test_empty_input() BOOST_CHECK_MESSAGE(bg::is_empty(hull), "Output convex hull should be empty" ); } - - #endif diff --git a/test/algorithms/overlay/get_turns_linear_linear.cpp b/test/algorithms/overlay/get_turns_linear_linear.cpp index b6d0c8266..11b1453ea 100644 --- a/test/algorithms/overlay/get_turns_linear_linear.cpp +++ b/test/algorithms/overlay/get_turns_linear_linear.cpp @@ -285,21 +285,12 @@ void test_all() "LINESTRING(2 8,4 0.4,8 1,0 5)", expected("iuu++")("mui=+")("tiu+=")); -#if ! ( defined(BOOST_CLANG) && defined(BOOST_GEOMETRY_COMPILER_MODE_RELEASE) ) - - // In clang/release mode this testcase gives other results - - // assertion failure in 1.57 - // FAILING - no assertion failure but the result is not very good test_geometry("LINESTRING(-2305843009213693956 4611686018427387906, -33 -92, 78 83)", "LINESTRING(31 -97, -46 57, -20 -4)", - expected("")("")); + expected("iuu++")); test_geometry("LINESTRING(31 -97, -46 57, -20 -4)", "LINESTRING(-2305843009213693956 4611686018427387906, -33 -92, 78 83)", - expected("")("")); - -#endif - + expected("iuu++")); } // In 1.57 the results of those combinations was different for MinGW diff --git a/test/algorithms/set_operations/sym_difference/sym_difference_tupled.cpp b/test/algorithms/set_operations/sym_difference/sym_difference_tupled.cpp index 0985ed410..9730935fc 100644 --- a/test/algorithms/set_operations/sym_difference/sym_difference_tupled.cpp +++ b/test/algorithms/set_operations/sym_difference/sym_difference_tupled.cpp @@ -348,7 +348,7 @@ inline void test_aa() "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))," "((2 6, 2 8, 8 8, 8 5, 7 5, 7 6, 2 6)))", "MULTIPOLYGON(((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0))," - "((5 0, 5 1, 6 1, 6 4, 5 4, 3 6, 2 5, 2 7, 7 7, 7 0 5 0)))", + "((5 0, 5 1, 6 1, 6 4, 5 4, 3 6, 2 5, 2 7, 7 7, 7 0, 5 0)))", "MULTIPOINT()", "MULTILINESTRING()", "MULTIPOLYGON(((0 0,0 5,4 5,3 6,7 6,7 7,2 7,2 8,8 8,8 5,7 5,7 0,0 0)," From c2c4569b8803c4a4cf3956fa81fab03d807164a0 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 12 Jun 2021 13:17:44 +0200 Subject: [PATCH 02/74] Add support for input DG and GC in is_empty() and convex_hull(). --- .../detail/convex_hull/graham_andrew.hpp | 116 +++--- .../detail/convex_hull/interface.hpp | 390 +++++++++--------- .../detail/select_geometry_type.hpp | 71 +++- .../boost/geometry/algorithms/is_empty.hpp | 60 +-- .../geometry/geometries/concepts/check.hpp | 9 +- .../convex_hull/test_convex_hull.hpp | 84 +--- 6 files changed, 342 insertions(+), 388 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/convex_hull/graham_andrew.hpp b/include/boost/geometry/algorithms/detail/convex_hull/graham_andrew.hpp index 9584f6a2f..7f3d61567 100644 --- a/include/boost/geometry/algorithms/detail/convex_hull/graham_andrew.hpp +++ b/include/boost/geometry/algorithms/detail/convex_hull/graham_andrew.hpp @@ -23,20 +23,19 @@ #include #include -#include -#include -#include -#include - #include #include +#include #include #include +#include #include #include #include #include +#include + namespace boost { namespace geometry { @@ -45,13 +44,15 @@ namespace boost { namespace geometry namespace detail { namespace convex_hull { -template -inline void get_extremes(Geometry const& geometry, +// TODO: All of the copies could be avoided if this function stored pointers to points. +// But would it be possible considering that a range can return proxy reference? +template +inline void get_extremes(Ranges const& ranges, Point& left, Point& right, Less const& less) { bool first = true; - geometry::detail::for_each_range(geometry, [&](auto const& range) + ranges.for_each_range([&](auto const& range) { if (boost::empty(range)) { @@ -107,19 +108,13 @@ inline void get_extremes(Geometry const& geometry, } -template -< - typename Geometry, - typename Point, - typename Container, - typename SideStrategy -> -inline void assign_ranges(Geometry const& geometry, +template +inline void assign_ranges(Ranges const& ranges, Point const& most_left, Point const& most_right, Container& lower_points, Container& upper_points, SideStrategy const& side) { - geometry::detail::for_each_range(geometry, [&](auto const& range) + ranges.for_each_range([&](auto const& range) { // Put points in one of the two output sequences for (auto it = boost::begin(range); it != boost::end(range); ++it) @@ -145,34 +140,17 @@ inline void assign_ranges(Geometry const& geometry, } -template -inline void sort(Range& range, Less const& less) -{ - std::sort(boost::begin(range), boost::end(range), less); -} - -} // namespace convex_hull - - /*! \brief Graham scan algorithm to calculate convex hull */ -template +template class graham_andrew { -public : - typedef OutputPoint point_type; - typedef InputGeometry geometry_type; - -private: - - typedef typename cs_tag::type cs_tag; - + typedef InputPoint point_type; typedef typename std::vector container_type; typedef typename std::vector::const_iterator iterator; typedef typename std::vector::const_reverse_iterator rev_iterator; - class partitions { friend class graham_andrew; @@ -182,14 +160,23 @@ private: container_type m_copied_input; }; - public: - typedef partitions state_type; + template + static void apply(InputRanges const& ranges, OutputRing & out_ring, Strategy& strategy) + { + partitions state; - template - inline void apply(InputGeometry const& geometry, - partitions& state, - Strategy& strategy) const + apply(ranges, state, strategy); + + result(state, + range::back_inserter(out_ring), + geometry::point_order::value == clockwise, + geometry::closure::value != open); + } + +private: + template + static void apply(InputRanges const& ranges, partitions& state, Strategy& strategy) { // First pass. // Get min/max (in most cases left / right) points @@ -203,14 +190,12 @@ public: // For symmetry and to get often more balanced lower/upper halves // we keep it. - typedef typename geometry::point_type::type point_type; - point_type most_left, most_right; // TODO: User-defined CS-specific less-compare geometry::less less; - detail::convex_hull::get_extremes(geometry, most_left, most_right, less); + detail::convex_hull::get_extremes(ranges, most_left, most_right, less); container_type lower_points, upper_points; @@ -219,13 +204,13 @@ public: // Bounding left/right points // Second pass, now that extremes are found, assign all points // in either lower, either upper - detail::convex_hull::assign_ranges(geometry, most_left, most_right, + detail::convex_hull::assign_ranges(ranges, most_left, most_right, lower_points, upper_points, side_strategy); // Sort both collections, first on x(, then on y) - detail::convex_hull::sort(lower_points, less); - detail::convex_hull::sort(upper_points, less); + std::sort(boost::begin(lower_points), boost::end(lower_points), less); + std::sort(boost::begin(upper_points), boost::end(upper_points), less); // And decide which point should be in the final hull build_half_hull<-1>(lower_points, state.m_lower_hull, @@ -236,26 +221,6 @@ public: side_strategy); } - - template - inline void result(partitions const& state, - OutputIterator out, - bool clockwise, - bool closed) const - { - if (clockwise) - { - output_ranges(state.m_upper_hull, state.m_lower_hull, out, closed); - } - else - { - output_ranges(state.m_lower_hull, state.m_upper_hull, out, closed); - } - } - - -private: - template static inline void build_half_hull(container_type const& input, container_type& output, @@ -300,6 +265,19 @@ private: } + template + static void result(partitions const& state, OutputIterator out, bool clockwise, bool closed) + { + if (clockwise) + { + output_ranges(state.m_upper_hull, state.m_lower_hull, out, closed); + } + else + { + output_ranges(state.m_lower_hull, state.m_upper_hull, out, closed); + } + } + template static inline void output_ranges(container_type const& first, container_type const& second, @@ -327,7 +305,7 @@ private: }; -} // namespace detail +}} // namespace detail::convex_hull #endif // DOXYGEN_NO_DETAIL }} // namespace boost::geometry diff --git a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp index ce61c9980..55dd625bc 100644 --- a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp +++ b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp @@ -23,27 +23,36 @@ #include -#include -#include -#include - #include #include #include +#include +#include +#include #include #include #include #include +#include #include #include +#include +#include +#include +#include // For backward compatibility #include +#include -#include +#include +#include +#include #include #include +#include +#include namespace boost { namespace geometry @@ -54,53 +63,79 @@ namespace boost { namespace geometry namespace detail { namespace convex_hull { -template -struct hull_insert +// Abstraction representing ranges/rings of a geometry +template +struct geometry_ranges { - // Member template function (to avoid inconvenient declaration - // of output-iterator-type, from hull_to_geometry) - template - static inline OutputIterator apply(Geometry const& geometry, - OutputIterator out, - Strategy const& strategy) + geometry_ranges(Geometry const& geometry) + : m_geometry(geometry) + {} + + template + inline void for_each_range(UnaryFunction fun) const { - typedef graham_andrew - < - Geometry, - typename point_type::type - > ConvexHullAlgorithm; - - ConvexHullAlgorithm algorithm; - typename ConvexHullAlgorithm::state_type state; - - algorithm.apply(geometry, state, strategy); - algorithm.result(state, out, Order == clockwise, Closure != open); - - return out; + geometry::detail::for_each_range(m_geometry, fun); } + + Geometry const& m_geometry; }; -struct hull_to_geometry +// Abstraction representing ranges/rings of subgeometries of geometry collection +// with boxes converted to rings +template +struct geometry_collection_ranges { - template - static inline void apply(Geometry const& geometry, OutputGeometry& out, - Strategy const& strategy) + geometry_collection_ranges(Geometry const& geometry, BoxRings const& box_rings) + : m_geometry(geometry) + , m_box_rings(box_rings) + {} + + template + inline void for_each_range(UnaryFunction fun) const { - // TODO: Why not handle multi-polygon here? - // TODO: detail::as_range() is only used in this place in the whole library - // it should probably be located here. - // NOTE: A variable is created here because this can be a proxy range - // and back_insert_iterator<> can store a pointer to it. - // Handle linestring, ring and polygon the same: - auto&& range = detail::as_range(out); - hull_insert - < - geometry::point_order::value, - geometry::closure::value - >::apply(geometry, range::back_inserter(range), strategy); + detail::visit_breadth_first([&](auto const& g) + { + call_for_non_boxes(g, fun); + return true; + }, m_geometry); + + for (auto const& r : m_box_rings) + { + geometry::detail::for_each_range(r, fun); + } } + +private: + template ::value, int> = 0> + static inline void call_for_non_boxes(G const& g, F & f) + { + geometry::detail::for_each_range(g, f); + } + template ::value, int> = 0> + static inline void call_for_non_boxes(G const&, F &) + {} + + Geometry const& m_geometry; + BoxRings const& m_box_rings; }; + +// TODO: Or just implement point_type<> for GeometryCollection +// and enforce the same point_type used in the whole sequence in check(). +template ::type> +struct default_strategy +{ + using type = typename strategies::convex_hull::services::default_strategy + < + Geometry + >::type; +}; + +template +struct default_strategy + : default_strategy::type> +{}; + }} // namespace detail::convex_hull #endif // DOXYGEN_NO_DETAIL @@ -116,8 +151,29 @@ template typename Tag = typename tag::type > struct convex_hull - : detail::convex_hull::hull_to_geometry -{}; +{ + template + static inline void apply(Geometry const& geometry, + OutputGeometry& out, + Strategy const& strategy) + { + detail::convex_hull::geometry_ranges ranges(geometry); + + // TODO: Why not handle multi-polygon here? + // TODO: detail::as_range() is only used in this place in the whole library + // it should probably be located here. + // NOTE: A variable is created here because this can be a proxy range + // and back_insert_iterator<> can store a pointer to it. + // Handle linestring, ring and polygon the same: + auto&& range = detail::as_range(out); + + detail::convex_hull::graham_andrew + < + typename point_type::type + >::apply(ranges, range, strategy); + } +}; + // TODO: This is not correct in spherical and geographic CS template @@ -135,6 +191,8 @@ struct convex_hull // A hull for boxes is trivial. Any strategy is (currently) skipped. boost::array::type, 4> range; + // TODO: This assigns only 2d cooridnates! + // And it is also used in box_view<>! geometry::detail::assign_box_corners_oriented(box, range); geometry::append(out, range); if (BOOST_GEOMETRY_CONDITION(Close)) @@ -145,11 +203,62 @@ struct convex_hull }; +template +struct convex_hull +{ + template + static inline void apply(GeometryCollection const& geometry, + OutputGeometry& out, + Strategy const& strategy) + { + // Assuming that single point_type is used by the GeometryCollection + using subgeometry_type = typename detail::first_geometry_type::type; + using point_type = typename geometry::point_type::type; + using ring_type = model::ring; -template -struct convex_hull_insert - : detail::convex_hull::hull_insert -{}; + // Calculate box rings once + std::vector box_rings; + detail::visit_breadth_first([&](auto const& g) + { + add_ring_for_box(box_rings, g, strategy); + return true; + }, geometry); + + detail::convex_hull::geometry_collection_ranges + < + GeometryCollection, std::vector + > ranges(geometry, box_rings); + + auto&& range = detail::as_range(out); + + detail::convex_hull::graham_andrew + < + point_type + >::apply(ranges, range, strategy); + } + +private: + template + < + typename Ring, typename SubGeometry, typename Strategy, + std::enable_if_t::value, int> = 0 + > + static inline void add_ring_for_box(std::vector & rings, SubGeometry const& box, + Strategy const& strategy) + { + Ring ring; + convex_hull::apply(box, ring, strategy); + rings.push_back(std::move(ring)); + } + template + < + typename Ring, typename SubGeometry, typename Strategy, + std::enable_if_t::value, int> = 0 + > + static inline void add_ring_for_box(std::vector & , SubGeometry const& , + Strategy const& ) + {} +}; } // namespace dispatch @@ -158,66 +267,42 @@ struct convex_hull_insert namespace resolve_strategy { +template struct convex_hull { - template - static inline void apply(Geometry const& geometry, - OutputGeometry& out, - Strategy const& strategy) - { - //BOOST_CONCEPT_ASSERT( (geometry::concepts::ConvexHullStrategy) ); - dispatch::convex_hull::apply(geometry, out, strategy); - } - template static inline void apply(Geometry const& geometry, OutputGeometry& out, - default_strategy) + Strategies const& strategies) { - typedef typename strategies::convex_hull::services::default_strategy - < - Geometry - >::type strategy_type; - - apply(geometry, out, strategy_type()); + dispatch::convex_hull::apply(geometry, out, strategies); } }; -struct convex_hull_insert +template <> +struct convex_hull { - template - static inline OutputIterator apply(Geometry const& geometry, - OutputIterator& out, - Strategy const& strategy) + template + static inline void apply(Geometry const& geometry, + OutputGeometry& out, + default_strategy const&) { - //BOOST_CONCEPT_ASSERT( (geometry::concepts::ConvexHullStrategy) ); - - return dispatch::convex_hull_insert< - geometry::point_order::value, - geometry::closure::value - >::apply(geometry, out, strategy); - } - - template - static inline OutputIterator apply(Geometry const& geometry, - OutputIterator& out, - default_strategy) - { - typedef typename strategies::convex_hull::services::default_strategy + using strategy_type = typename detail::convex_hull::default_strategy < Geometry - >::type strategy_type; + >::type; - return apply(geometry, out, strategy_type()); + dispatch::convex_hull::apply(geometry, out, strategy_type()); } }; + } // namespace resolve_strategy -namespace resolve_variant { +namespace resolve_dynamic { -template +template ::type> struct convex_hull { template @@ -230,88 +315,27 @@ struct convex_hull OutputGeometry >(); - resolve_strategy::convex_hull::apply(geometry, out, strategy); - } -}; - -template -struct convex_hull > -{ - template - struct visitor: boost::static_visitor - { - OutputGeometry& m_out; - Strategy const& m_strategy; - - visitor(OutputGeometry& out, Strategy const& strategy) - : m_out(out), m_strategy(strategy) - {} - - template - void operator()(Geometry const& geometry) const - { - convex_hull::apply(geometry, m_out, m_strategy); - } - }; - - template - static inline void - apply(boost::variant const& geometry, - OutputGeometry& out, - Strategy const& strategy) - { - boost::apply_visitor(visitor(out, strategy), - geometry); + resolve_strategy::convex_hull::apply(geometry, out, strategy); } }; template -struct convex_hull_insert +struct convex_hull { - template - static inline OutputIterator apply(Geometry const& geometry, - OutputIterator& out, - Strategy const& strategy) + template + static inline void apply(Geometry const& geometry, + OutputGeometry& out, + Strategy const& strategy) { - // Concept: output point type = point type of input geometry - concepts::check(); - concepts::check::type>(); - - return resolve_strategy::convex_hull_insert::apply(geometry, out, strategy); - } -}; - -template -struct convex_hull_insert > -{ - template - struct visitor: boost::static_visitor - { - OutputIterator& m_out; - Strategy const& m_strategy; - - visitor(OutputIterator& out, Strategy const& strategy) - : m_out(out), m_strategy(strategy) - {} - - template - OutputIterator operator()(Geometry const& geometry) const + traits::visit::apply([&](auto const& g) { - return convex_hull_insert::apply(geometry, m_out, m_strategy); - } - }; - - template - static inline OutputIterator - apply(boost::variant const& geometry, - OutputIterator& out, - Strategy const& strategy) - { - return boost::apply_visitor(visitor(out, strategy), geometry); + convex_hull>::apply(g, out, strategy); + }, geometry); } }; -} // namespace resolve_variant + +} // namespace resolve_dynamic /*! @@ -330,8 +354,7 @@ struct convex_hull_insert > \qbk{[include reference/algorithms/convex_hull.qbk]} */ template -inline void convex_hull(Geometry const& geometry, - OutputGeometry& out, Strategy const& strategy) +inline void convex_hull(Geometry const& geometry, OutputGeometry& out, Strategy const& strategy) { if (geometry::is_empty(geometry)) { @@ -339,7 +362,7 @@ inline void convex_hull(Geometry const& geometry, return; } - resolve_variant::convex_hull::apply(geometry, out, strategy); + resolve_dynamic::convex_hull::apply(geometry, out, strategy); } @@ -355,52 +378,11 @@ inline void convex_hull(Geometry const& geometry, \qbk{[include reference/algorithms/convex_hull.qbk]} */ template -inline void convex_hull(Geometry const& geometry, - OutputGeometry& hull) +inline void convex_hull(Geometry const& geometry, OutputGeometry& hull) { geometry::convex_hull(geometry, hull, default_strategy()); } -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace convex_hull -{ - - -template -inline OutputIterator convex_hull_insert(Geometry const& geometry, - OutputIterator out, Strategy const& strategy) -{ - return resolve_variant::convex_hull_insert - < - Geometry - >::apply(geometry, out, strategy); -} - - -/*! -\brief Calculate the convex hull of a geometry, output-iterator version -\ingroup convex_hull -\tparam Geometry the input geometry type -\tparam OutputIterator: an output-iterator -\param geometry the geometry to calculate convex hull from -\param out an output iterator outputing points of the convex hull -\note This overloaded version outputs to an output iterator. -In this case, nothing is known about its point-type or - about its clockwise order. Therefore, the input point-type - and order are copied - - */ -template -inline OutputIterator convex_hull_insert(Geometry const& geometry, - OutputIterator out) -{ - return convex_hull_insert(geometry, out, default_strategy()); -} - - -}} // namespace detail::convex_hull -#endif // DOXYGEN_NO_DETAIL - }} // namespace boost::geometry diff --git a/include/boost/geometry/algorithms/detail/select_geometry_type.hpp b/include/boost/geometry/algorithms/detail/select_geometry_type.hpp index 2e94ae73e..235adca9f 100644 --- a/include/boost/geometry/algorithms/detail/select_geometry_type.hpp +++ b/include/boost/geometry/algorithms/detail/select_geometry_type.hpp @@ -11,6 +11,9 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SELECT_GEOMETRY_TYPE_HPP #include +#include +#include +#include #include #include @@ -21,6 +24,56 @@ namespace boost { namespace geometry namespace detail { + +template ::type> +struct first_geometry_type +{ + using type = Geometry; +}; + +template +struct first_geometry_type +{ + BOOST_GEOMETRY_STATIC_ASSERT_FALSE("Not implemented for this Geometry", + Geometry, dynamic_geometry_tag); +}; + +template +struct first_geometry_type +{ + template + using pred = util::bool_constant + < + ! util::is_dynamic_geometry::value + && ! util::is_geometry_collection::value + >; + + using type = typename util::sequence_find_if + < + typename traits::geometry_types::type, + pred + >::type; +}; + + +template +< + typename Geometry, + bool IsDynamicOrCollection = util::is_dynamic_geometry::value + || util::is_geometry_collection::value +> +struct geometry_types +{ + using type = util::type_sequence>; +}; + +template +struct geometry_types +{ + using type = typename traits::geometry_types>::type; +}; + + template < typename Geometry, @@ -47,24 +100,6 @@ struct select_geometry_type {}; -template -< - typename Geometry, - bool IsDynamicOrCollection = util::is_dynamic_geometry::value - || util::is_geometry_collection::value -> -struct geometry_types -{ - using type = util::type_sequence>; -}; - -template -struct geometry_types -{ - using type = typename traits::geometry_types>::type; -}; - - template < typename Geometry1, typename Geometry2, diff --git a/include/boost/geometry/algorithms/is_empty.hpp b/include/boost/geometry/algorithms/is_empty.hpp index 3fe5359fa..52c308214 100644 --- a/include/boost/geometry/algorithms/is_empty.hpp +++ b/include/boost/geometry/algorithms/is_empty.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2015-2020, Oracle and/or its affiliates. +// Copyright (c) 2015-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 @@ -15,21 +15,21 @@ #include #include -#include -#include -#include +#include +#include +#include #include +#include #include #include #include +#include -#include - -#include - +#include // For backward compatibility #include +#include namespace boost { namespace geometry { @@ -152,10 +152,10 @@ struct is_empty #endif // DOXYGEN_NO_DISPATCH -namespace resolve_variant +namespace resolve_dynamic { -template +template ::type> struct is_empty { static inline bool apply(Geometry const& geometry) @@ -166,26 +166,36 @@ struct is_empty } }; -template -struct is_empty > +template +struct is_empty { - struct visitor : boost::static_visitor + static inline bool apply(Geometry const& geometry) { - template - inline bool operator()(Geometry const& geometry) const + bool result = true; + traits::visit::apply([&](auto const& g) { - return is_empty::apply(geometry); - } - }; - - static bool - apply(boost::variant const& geometry) - { - return boost::apply_visitor(visitor(), geometry); + result = is_empty>::apply(g); + }, geometry); + return result; } }; -} // namespace resolve_variant +template +struct is_empty +{ + static inline bool apply(Geometry const& geometry) + { + bool result = true; + detail::visit_breadth_first([&](auto const& g) + { + result = is_empty>::apply(g); + return result; + }, geometry); + return result; + } +}; + +} // namespace resolve_dynamic /*! @@ -200,7 +210,7 @@ struct is_empty > template inline bool is_empty(Geometry const& geometry) { - return resolve_variant::is_empty::apply(geometry); + return resolve_dynamic::is_empty::apply(geometry); } diff --git a/include/boost/geometry/geometries/concepts/check.hpp b/include/boost/geometry/geometries/concepts/check.hpp index 5f5923864..34eb74032 100644 --- a/include/boost/geometry/geometries/concepts/check.hpp +++ b/include/boost/geometry/geometries/concepts/check.hpp @@ -22,6 +22,8 @@ #include #include +#include + #include #include #include @@ -39,7 +41,6 @@ namespace boost { namespace geometry { namespace concepts { - /*! \brief Checks, in compile-time, the concept of any geometry \ingroup concepts @@ -69,7 +70,11 @@ inline void check_concepts_and_equal_dimensions() { check(); check(); - assert_dimension_equal(); + assert_dimension_equal + < + typename geometry::detail::first_geometry_type::type, + typename geometry::detail::first_geometry_type::type + >(); } diff --git a/test/algorithms/convex_hull/test_convex_hull.hpp b/test/algorithms/convex_hull/test_convex_hull.hpp index df1b959b0..54c683f84 100644 --- a/test/algorithms/convex_hull/test_convex_hull.hpp +++ b/test/algorithms/convex_hull/test_convex_hull.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014, 2015. -// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014-2021. +// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -16,8 +16,6 @@ #ifndef BOOST_GEOMETRY_TEST_CONVEX_HULL_HPP #define BOOST_GEOMETRY_TEST_CONVEX_HULL_HPP -#include - #include #include @@ -26,6 +24,9 @@ #include #include +#include +#include + #include #include #include @@ -119,31 +120,6 @@ void check_convex_hull(Geometry const& geometry, Hull const& hull, } } -namespace resolve_variant { - -struct closure_visitor : public boost::static_visitor -{ - template - bg::closure_selector operator()(Geometry const&) const - { - return bg::closure::value; - } -}; - -template -inline bg::closure_selector get_closure(Geometry const&) -{ - return bg::closure::value; -} - -template -inline bg::closure_selector get_closure(boost::variant const& v) -{ - return boost::apply_visitor(closure_visitor(), v); -} - -} // namespace resolve_variant - template < @@ -161,32 +137,16 @@ struct test_convex_hull double expected_perimeter, bool reverse) { - bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open; static bool const is_hull_closed = bg::closure::value != bg::open; - - // convex_hull_insert() uses the original Geometry as a source of the info - // about the order and closure - std::size_t const size_hull_from_orig = is_original_closed ? - size_hull_closed : size_hull_closed - 1; std::size_t const size_hull = is_hull_closed ? size_hull_closed : size_hull_closed - 1; Hull hull; - - // Test version with strategy - bg::clear(hull); bg::convex_hull(geometry, hull.outer(), Strategy()); + check_convex_hull(geometry, hull, size_original, size_hull, expected_area, expected_perimeter, false, AreaStrategy()); - // Test version with output iterator and strategy - bg::clear(hull); - bg::detail::convex_hull::convex_hull_insert( - geometry, - std::back_inserter(hull.outer()), Strategy()); - check_convex_hull(geometry, hull, size_original, size_hull_from_orig, - expected_area, expected_perimeter, reverse, AreaStrategy()); - } }; @@ -206,27 +166,12 @@ struct test_convex_hull double expected_perimeter, bool reverse) { - bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open; static bool const is_hull_closed = bg::closure::value != bg::open; - - // convex_hull_insert() uses the original Geometry as a source of the info - // about the order and closure - std::size_t const size_hull_from_orig = is_original_closed ? - size_hull_closed : size_hull_closed - 1; std::size_t const size_hull = is_hull_closed ? size_hull_closed : size_hull_closed - 1; - Hull hull; - - // Test version with output iterator - bg::detail::convex_hull::convex_hull_insert(geometry, - std::back_inserter(hull.outer())); - check_convex_hull(geometry, hull, size_original, size_hull_from_orig, - expected_area, expected_perimeter, reverse, - AreaStrategy()); - // Test version with ring as output - bg::clear(hull); + Hull hull; bg::convex_hull(geometry, hull.outer()); check_convex_hull(geometry, hull, size_original, size_hull, expected_area, expected_perimeter, false, AreaStrategy()); @@ -243,13 +188,6 @@ struct test_convex_hull check_convex_hull(geometry, hull, size_original, size_hull, expected_area, expected_perimeter, false, AreaStrategy()); - // Test version with output iterator and strategy - bg::clear(hull); - bg::detail::convex_hull::convex_hull_insert(geometry, - std::back_inserter(hull.outer()), robust_cartesian()); - check_convex_hull(geometry, hull, size_original, size_hull_from_orig, - expected_area, expected_perimeter, reverse, AreaStrategy()); - } }; @@ -282,9 +220,15 @@ void test_geometry_order(std::string const& wkt, test_convex_hull::apply(geometry, size_original, size_hull_closed, expected_area, expected_perimeter, !Clockwise); - boost::variant v(geometry); + using variant_t = boost::variant; + + variant_t v(geometry); test_convex_hull::apply(v, size_original, size_hull_closed, expected_area, expected_perimeter, !Clockwise); + + bg::model::geometry_collection gc = { v }; + test_convex_hull::apply(gc, size_original, + size_hull_closed, expected_area, expected_perimeter, !Clockwise); } template From d3be761ac5f7b81e8686da5a59aeef2e213ce08b Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 21 Jun 2021 17:21:41 +0200 Subject: [PATCH 03/74] Add support for output GeometryCollection in convex_hull. Add relate(pt, pt) to convex_hull umbrella strategy. Add several util::enable_if_xxx type traits. Remove detail::as_range(). Update the tests. --- .../geometry/algorithms/detail/as_range.hpp | 91 ------ .../detail/convex_hull/interface.hpp | 268 ++++++++++++++++-- .../strategies/convex_hull/cartesian.hpp | 17 +- .../strategies/convex_hull/geographic.hpp | 16 +- .../strategies/convex_hull/spherical.hpp | 16 +- .../strategies/is_convex/cartesian.hpp | 19 +- .../strategies/is_convex/geographic.hpp | 25 +- .../strategies/is_convex/spherical.hpp | 19 +- include/boost/geometry/util/type_traits.hpp | 16 ++ .../convex_hull/test_convex_hull.hpp | 29 +- test/algorithms/detail/Jamfile | 1 - test/algorithms/detail/as_range.cpp | 77 ----- 12 files changed, 338 insertions(+), 256 deletions(-) delete mode 100644 include/boost/geometry/algorithms/detail/as_range.hpp delete mode 100644 test/algorithms/detail/as_range.cpp diff --git a/include/boost/geometry/algorithms/detail/as_range.hpp b/include/boost/geometry/algorithms/detail/as_range.hpp deleted file mode 100644 index fe2016be5..000000000 --- a/include/boost/geometry/algorithms/detail/as_range.hpp +++ /dev/null @@ -1,91 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. - -// This file was modified by Oracle on 2020-2021. -// Modifications copyright (c) 2020-2021 Oracle and/or its affiliates. -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - -// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library -// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. - -// Use, modification and distribution is subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_AS_RANGE_HPP -#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_AS_RANGE_HPP - - -#include - -#include -#include -#include -#include - - -namespace boost { namespace geometry -{ - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - -template ::type> -struct as_range : not_implemented -{}; - -template -struct as_range -{ - static inline typename ring_return_type::type get(Geometry& geometry) - { - return geometry; - } -}; - -template -struct as_range - : as_range -{}; - -template -struct as_range -{ - static inline typename ring_return_type::type get(Geometry& geometry) - { - return exterior_ring(geometry); - } -}; - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - -// Will probably be replaced by the more generic "view_as", therefore in detail -namespace detail -{ - -/*! -\brief Function getting either the range (ring, linestring) itself -or the outer ring (polygon) -\details Utility to handle polygon's outer ring as a range -\ingroup utility -*/ -template -inline typename ring_return_type::type as_range(Geometry& geometry) -{ - return dispatch::as_range::get(geometry); -} - -} - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_AS_RANGE_HPP diff --git a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp index 55dd625bc..a2730c3f3 100644 --- a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp +++ b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp @@ -21,11 +21,11 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_INTERFACE_HPP #define BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_INTERFACE_HPP -#include +#include -#include #include #include +#include #include #include #include @@ -51,6 +51,7 @@ #include #include +#include #include #include @@ -58,6 +59,8 @@ namespace boost { namespace geometry { +// TODO: This file is named interface.hpp but the code below is not the interface. +// It's the implementation of the algorithm. #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace convex_hull @@ -136,6 +139,216 @@ struct default_strategy : default_strategy::type> {}; + +// Wrapper for output geometry. It contains reference to OutputGeometry and may contain +// a temporary geometry which is moved to the output at the end of the algorithm. +template ::type> +struct output_geometry +{ + BOOST_GEOMETRY_STATIC_ASSERT_FALSE("This OutputGeometry is not supported.", OutputGeometry, Tag); +}; + +// For backward compatibility +template +struct output_geometry +{ + output_geometry(OutputGeometry & out) : m_out(out) {} + OutputGeometry & range() { return m_out; } + template + void move_to_out(Strategy const& ) {} +private: + OutputGeometry & m_out; +}; + +template +struct output_geometry +{ + output_geometry(OutputGeometry & out) : m_out(out) {} + OutputGeometry & range() { return m_out; } + template + void move_to_out(Strategy const& ) {} +private: + OutputGeometry & m_out; +}; + +template +struct output_geometry +{ + output_geometry(OutputGeometry & out) : m_out(out) {} + decltype(auto) range() { return exterior_ring(m_out); } + template + void move_to_out(Strategy const& ) {} +private: + OutputGeometry & m_out; +}; + +template +struct output_geometry +{ + output_geometry(OutputGeometry & out) : m_out(out) {} + decltype(auto) range() { return exterior_ring(m_polygon); } + template + void move_to_out(Strategy const& ) + { + if (! boost::empty(exterior_ring(m_polygon))) + { + range::push_back(m_out, std::move(m_polygon)); + } + } +private: + OutputGeometry & m_out; + typename boost::range_value::type m_polygon; +}; + +template +struct output_polygonal_less +{ + template + using priority = std::integral_constant + < + int, + (util::is_ring::value ? 0 : + util::is_polygon::value ? 1 : + util::is_multi_polygon::value ? 2 : 3) + >; + + static const bool value = priority::value < priority::value; +}; + +template +struct output_linear_less +{ + template + using priority = std::integral_constant + < + int, + (util::is_segment::value ? 0 : + util::is_linestring::value ? 1 : + util::is_multi_linestring::value ? 2 : 3) + >; + + static const bool value = priority::value < priority::value; +}; + +template +struct output_pointlike_less +{ + template + using priority = std::integral_constant + < + int, + (util::is_point::value ? 0 : + util::is_multi_point::value ? 1 : 2) + >; + + static const bool value = priority::value < priority::value; +}; + +template +struct output_geometry +{ + using polygonal_t = typename util::select_element + < + typename traits::geometry_types::type, + output_polygonal_less + >::type; + using linear_t = typename util::select_element + < + typename traits::geometry_types::type, + output_linear_less + >::type; + using pointlike_t = typename util::select_element + < + typename traits::geometry_types::type, + output_pointlike_less + >::type; + + // select_element may define different kind of geometry than the one that is desired + BOOST_GEOMETRY_STATIC_ASSERT(util::is_polygonal::value, + "It must be possible to store polygonal geometry in GeometryCollection.", polygonal_t); + BOOST_GEOMETRY_STATIC_ASSERT(util::is_linear::value, + "It must be possible to store linear geometry in GeometryCollection.", linear_t); + BOOST_GEOMETRY_STATIC_ASSERT(util::is_pointlike::value, + "It must be possible to store pointlike geometry in GeometryCollection.", pointlike_t); + + output_geometry(OutputGeometry & out) + : m_out(out), m_wrapper(m_polygonal) + {} + + decltype(auto) range() { return m_wrapper.range(); } + + template + void move_to_out(Strategy const& strategy) + { + auto&& out_range = m_wrapper.range(); + if (! boost::empty(out_range)) + { + auto size = boost::size(out_range); + if (size > minimum_ring_size::value) + { + m_wrapper.move_to_out(strategy); + range::emplace_back(m_out, std::move(m_polygonal)); + } + else // size == 3 || size == 4 + { + if (detail::equals::equals_point_point(range::front(out_range), range::at(out_range, 1), strategy)) + { + pointlike_t pointlike; + move_to_pointlike(out_range, pointlike); + range::emplace_back(m_out, std::move(pointlike)); + } + else if (detail::equals::equals_point_point(range::front(out_range), range::at(out_range, 2), strategy)) + { + linear_t linear; + move_to_linear(out_range, linear); + range::emplace_back(m_out, std::move(linear)); + } + else + { + m_wrapper.move_to_out(strategy); + range::emplace_back(m_out, std::move(m_polygonal)); + } + } + } + } + +private: + template = 0> + static void move_to_linear(Range & out_range, Linear & seg) + { + detail::assign_point_to_index<0>(range::front(out_range), seg); + detail::assign_point_to_index<1>(range::at(out_range, 1), seg); + } + template = 0> + static void move_to_linear(Range & out_range, Linear & ls) + { + std::move(boost::begin(out_range), boost::begin(out_range) + 2, range::back_inserter(ls)); + } + template = 0> + static void move_to_linear(Range & out_range, Linear & mls) + { + typename boost::range_value::type ls; + std::move(boost::begin(out_range), boost::begin(out_range) + 2, range::back_inserter(ls)); + range::push_back(mls, std::move(ls)); + } + + template = 0> + static void move_to_pointlike(Range & out_range, PointLike & pt) + { + pt = range::front(out_range); + } + template = 0> + static void move_to_pointlike(Range & out_range, PointLike & mpt) + { + range::push_back(mpt, std::move(range::front(out_range))); + } + + OutputGeometry & m_out; + polygonal_t m_polygonal; + output_geometry m_wrapper; +}; + + }} // namespace detail::convex_hull #endif // DOXYGEN_NO_DETAIL @@ -159,46 +372,54 @@ struct convex_hull { detail::convex_hull::geometry_ranges ranges(geometry); - // TODO: Why not handle multi-polygon here? - // TODO: detail::as_range() is only used in this place in the whole library - // it should probably be located here. + detail::convex_hull::output_geometry out_wrapper(out); // NOTE: A variable is created here because this can be a proxy range // and back_insert_iterator<> can store a pointer to it. - // Handle linestring, ring and polygon the same: - auto&& range = detail::as_range(out); + auto&& out_range = out_wrapper.range(); detail::convex_hull::graham_andrew < typename point_type::type - >::apply(ranges, range, strategy); + >::apply(ranges, out_range, strategy); + + out_wrapper.move_to_out(strategy); } }; -// TODO: This is not correct in spherical and geographic CS +// A hull for boxes is trivial. Any strategy is (currently) skipped. +// TODO: This is not correct in spherical and geographic CS. template struct convex_hull { template static inline void apply(Box const& box, OutputGeometry& out, - Strategy const& ) + Strategy const& strategy) { - static bool const Close - = geometry::closure::value == closed; - static bool const Reverse - = geometry::point_order::value == counterclockwise; + detail::convex_hull::output_geometry out_wrapper(out); + // NOTE: A variable is created here because this can be a proxy range + // and back_insert_iterator<> can store a pointer to it. + auto&& out_range = out_wrapper.range(); - // A hull for boxes is trivial. Any strategy is (currently) skipped. - boost::array::type, 4> range; + using out_range_t = std::remove_reference_t; + static bool const Close + = geometry::closure::value == closed; + static bool const Reverse + = geometry::point_order::value == counterclockwise; + + std::array::type, 4> arr; // TODO: This assigns only 2d cooridnates! // And it is also used in box_view<>! - geometry::detail::assign_box_corners_oriented(box, range); - geometry::append(out, range); + geometry::detail::assign_box_corners_oriented(box, arr); + + std::move(arr.begin(), arr.end(), range::back_inserter(out_range)); if (BOOST_GEOMETRY_CONDITION(Close)) { - geometry::append(out, *boost::begin(range)); + range::push_back(out_range, range::front(out_range)); } + + out_wrapper.move_to_out(strategy); } }; @@ -229,12 +450,17 @@ struct convex_hull GeometryCollection, std::vector > ranges(geometry, box_rings); - auto&& range = detail::as_range(out); + detail::convex_hull::output_geometry out_wrapper(out); + // NOTE: A variable is created here because this can be a proxy range + // and back_insert_iterator<> can store a pointer to it. + auto&& out_range = out_wrapper.range(); detail::convex_hull::graham_andrew < point_type - >::apply(ranges, range, strategy); + >::apply(ranges, out_range, strategy); + + out_wrapper.move_to_out(strategy); } private: diff --git a/include/boost/geometry/strategies/convex_hull/cartesian.hpp b/include/boost/geometry/strategies/convex_hull/cartesian.hpp index 1bef4e389..d19dedeaf 100644 --- a/include/boost/geometry/strategies/convex_hull/cartesian.hpp +++ b/include/boost/geometry/strategies/convex_hull/cartesian.hpp @@ -1,8 +1,9 @@ // Boost.Geometry -// Copyright (c) 2020, Oracle and/or its affiliates. +// Copyright (c) 2020-2021, 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -11,9 +12,12 @@ #define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP +#include #include #include #include +#include + namespace boost { namespace geometry { @@ -25,6 +29,17 @@ template class cartesian : public strategies::detail::cartesian_base { public: + template + static auto relate(Geometry1 const&, Geometry2 const&, + std::enable_if_t + < + util::is_pointlike::value + && util::is_pointlike::value + > * = nullptr) + { + return strategy::within::cartesian_point_point(); + } + static auto side() { return strategy::side::side_robust(); diff --git a/include/boost/geometry/strategies/convex_hull/geographic.hpp b/include/boost/geometry/strategies/convex_hull/geographic.hpp index 9f4a367eb..cb7445db4 100644 --- a/include/boost/geometry/strategies/convex_hull/geographic.hpp +++ b/include/boost/geometry/strategies/convex_hull/geographic.hpp @@ -1,8 +1,9 @@ // Boost.Geometry -// Copyright (c) 2020, Oracle and/or its affiliates. +// Copyright (c) 2020-2021, 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -14,6 +15,8 @@ #include #include #include +#include +#include namespace boost { namespace geometry @@ -39,6 +42,17 @@ public: : base_t(spheroid) {} + template + static auto relate(Geometry1 const&, Geometry2 const&, + std::enable_if_t + < + util::is_pointlike::value + && util::is_pointlike::value + > * = nullptr) + { + return strategy::within::spherical_point_point(); + } + auto side() const { return strategy::side::geographic diff --git a/include/boost/geometry/strategies/convex_hull/spherical.hpp b/include/boost/geometry/strategies/convex_hull/spherical.hpp index 0eec8ee82..a637a0248 100644 --- a/include/boost/geometry/strategies/convex_hull/spherical.hpp +++ b/include/boost/geometry/strategies/convex_hull/spherical.hpp @@ -1,8 +1,9 @@ // Boost.Geometry -// Copyright (c) 2020, Oracle and/or its affiliates. +// Copyright (c) 2020-2021, 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -13,7 +14,9 @@ #include #include +#include #include +#include namespace boost { namespace geometry @@ -26,6 +29,17 @@ template class spherical : public strategies::detail::spherical_base { public: + template + static auto relate(Geometry1 const&, Geometry2 const&, + std::enable_if_t + < + util::is_pointlike::value + && util::is_pointlike::value + > * = nullptr) + { + return strategy::within::spherical_point_point(); + } + static auto side() { return strategy::side::spherical_side_formula(); diff --git a/include/boost/geometry/strategies/is_convex/cartesian.hpp b/include/boost/geometry/strategies/is_convex/cartesian.hpp index 4297c223b..c7afa2fc0 100644 --- a/include/boost/geometry/strategies/is_convex/cartesian.hpp +++ b/include/boost/geometry/strategies/is_convex/cartesian.hpp @@ -11,12 +11,10 @@ #define BOOST_GEOMETRY_STRATEGIES_IS_CONVEX_CARTESIAN_HPP -#include #include #include #include #include -#include namespace boost { namespace geometry @@ -25,21 +23,10 @@ namespace boost { namespace geometry namespace strategies { namespace is_convex { + template -class cartesian : public strategies::convex_hull::cartesian -{ -public: - template - static auto relate(Geometry1 const&, Geometry2 const&, - std::enable_if_t - < - util::is_pointlike::value - && util::is_pointlike::value - > * = nullptr) - { - return strategy::within::cartesian_point_point(); - } -}; +using cartesian = strategies::convex_hull::cartesian; + namespace services { diff --git a/include/boost/geometry/strategies/is_convex/geographic.hpp b/include/boost/geometry/strategies/is_convex/geographic.hpp index 66660138f..dd27c981a 100644 --- a/include/boost/geometry/strategies/is_convex/geographic.hpp +++ b/include/boost/geometry/strategies/is_convex/geographic.hpp @@ -14,8 +14,6 @@ #include #include #include -#include -#include namespace boost { namespace geometry @@ -24,34 +22,15 @@ namespace boost { namespace geometry namespace strategies { namespace is_convex { + template < typename FormulaPolicy = strategy::andoyer, typename Spheroid = srs::spheroid, typename CalculationType = void > -class geographic : public strategies::convex_hull::geographic -{ - using base_t = strategies::convex_hull::geographic; +using geographic = strategies::convex_hull::geographic; -public: - geographic() = default; - - explicit geographic(Spheroid const& spheroid) - : base_t(spheroid) - {} - - template - static auto relate(Geometry1 const&, Geometry2 const&, - std::enable_if_t - < - util::is_pointlike::value - && util::is_pointlike::value - > * = nullptr) - { - return strategy::within::spherical_point_point(); - } -}; namespace services { diff --git a/include/boost/geometry/strategies/is_convex/spherical.hpp b/include/boost/geometry/strategies/is_convex/spherical.hpp index 06ff3fae8..c6e97d16d 100644 --- a/include/boost/geometry/strategies/is_convex/spherical.hpp +++ b/include/boost/geometry/strategies/is_convex/spherical.hpp @@ -14,8 +14,6 @@ #include #include #include -#include -#include namespace boost { namespace geometry @@ -24,21 +22,10 @@ namespace boost { namespace geometry namespace strategies { namespace is_convex { + template -class spherical : public strategies::convex_hull::spherical -{ -public: - template - static auto relate(Geometry1 const&, Geometry2 const&, - std::enable_if_t - < - util::is_pointlike::value - && util::is_pointlike::value - > * = nullptr) - { - return strategy::within::spherical_point_point(); - } -}; +using spherical = strategies::convex_hull::spherical; + namespace services { diff --git a/include/boost/geometry/util/type_traits.hpp b/include/boost/geometry/util/type_traits.hpp index f1f89a7a1..7ad4c71bc 100644 --- a/include/boost/geometry/util/type_traits.hpp +++ b/include/boost/geometry/util/type_traits.hpp @@ -182,6 +182,22 @@ struct enable_if_segment template using enable_if_segment_t = typename enable_if_segment::type; +template +struct enable_if_linestring + : std::enable_if::value, T> +{}; + +template +using enable_if_linestring_t = typename enable_if_linestring::type; + +template +struct enable_if_multi_linestring + : std::enable_if::value, T> +{}; + +template +using enable_if_multi_linestring_t = typename enable_if_multi_linestring::type; + template struct enable_if_polylinear diff --git a/test/algorithms/convex_hull/test_convex_hull.hpp b/test/algorithms/convex_hull/test_convex_hull.hpp index 54c683f84..e77584072 100644 --- a/test/algorithms/convex_hull/test_convex_hull.hpp +++ b/test/algorithms/convex_hull/test_convex_hull.hpp @@ -26,9 +26,9 @@ #include #include +#include #include -#include #include #include @@ -40,7 +40,7 @@ #include -struct robust_cartesian : boost::geometry::strategies::detail::cartesian_base +struct robust_cartesian : boost::geometry::strategies::convex_hull::cartesian<> { static auto side() { @@ -48,7 +48,7 @@ struct robust_cartesian : boost::geometry::strategies::detail::cartesian_base } }; -struct non_robust_cartesian_fast : boost::geometry::strategies::detail::cartesian_base +struct non_robust_cartesian_fast : boost::geometry::strategies::convex_hull::cartesian<> { static auto side() { @@ -56,7 +56,7 @@ struct non_robust_cartesian_fast : boost::geometry::strategies::detail::cartesia } }; -struct non_robust_cartesian_sbt : boost::geometry::strategies::detail::cartesian_base +struct non_robust_cartesian_sbt : boost::geometry::strategies::convex_hull::cartesian<> { static auto side() { @@ -65,7 +65,7 @@ struct non_robust_cartesian_sbt : boost::geometry::strategies::detail::cartesian }; template -struct sphrerical_side_by_cross_track : boost::geometry::strategies::detail::spherical_base +struct sphrerical_side_by_cross_track : boost::geometry::strategies::convex_hull::spherical<> { static auto side() { @@ -73,7 +73,7 @@ struct sphrerical_side_by_cross_track : boost::geometry::strategies::detail::sph } }; -struct precise_cartesian : boost::geometry::strategies::detail::cartesian_base +struct precise_cartesian : boost::geometry::strategies::area::cartesian<> { template static auto area(Geometry const&) @@ -135,7 +135,7 @@ struct test_convex_hull std::size_t size_hull_closed, double expected_area, double expected_perimeter, - bool reverse) + bool ) { static bool const is_hull_closed = bg::closure::value != bg::open; std::size_t const size_hull = is_hull_closed ? size_hull_closed : @@ -147,6 +147,19 @@ struct test_convex_hull check_convex_hull(geometry, hull, size_original, size_hull, expected_area, expected_perimeter, false, AreaStrategy()); + bg::convex_hull(geometry, hull, Strategy()); + + using point_t = typename bg::point_type::type; + using var_t = boost::variant, point_t>; + using gc_t = bg::model::geometry_collection; + gc_t gc; + bg::convex_hull(geometry, gc, Strategy()); + if (bg::detail::equals::equals_point_point(hull.outer()[0], hull.outer()[1], Strategy())) + BOOST_CHECK(gc[0].which() == 2); // GC stores point + else if (bg::detail::equals::equals_point_point(hull.outer()[0], hull.outer()[2], Strategy())) + BOOST_CHECK(gc[0].which() == 1); // GC stores linestring + else + BOOST_CHECK(gc[0].which() == 0); // GC stores polygon } }; @@ -164,7 +177,7 @@ struct test_convex_hull std::size_t size_hull_closed, double expected_area, double expected_perimeter, - bool reverse) + bool ) { static bool const is_hull_closed = bg::closure::value != bg::open; std::size_t const size_hull = is_hull_closed ? size_hull_closed : diff --git a/test/algorithms/detail/Jamfile b/test/algorithms/detail/Jamfile index 3652df547..7b8d6e0b5 100644 --- a/test/algorithms/detail/Jamfile +++ b/test/algorithms/detail/Jamfile @@ -15,7 +15,6 @@ test-suite boost-geometry-algorithms-detail : - [ run as_range.cpp : : : : algorithms_as_range ] [ run calculate_point_order.cpp : : : : algorithms_calculate_point_order ] [ run approximately_equals.cpp : : : : algorithms_approximately_equals ] [ run partition.cpp : : : : algorithms_partition ] diff --git a/test/algorithms/detail/as_range.cpp b/test/algorithms/detail/as_range.cpp deleted file mode 100644 index f33cb49ce..000000000 --- a/test/algorithms/detail/as_range.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) -// Unit Test - -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. - -// This file was modified by Oracle on 2021. -// Modifications copyright (c) 2021 Oracle and/or its affiliates. -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - -// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library -// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. - -// Use, modification and distribution is subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#include - -#include - -#include -#include - -#include - - -template -double sum(Range const& range) -{ - double s = 0.0; - for (typename boost::range_const_iterator::type it = boost::begin(range); - it != boost::end(range); ++it) - { - s += bg::get(*it); - } - return s; -} - -template -void test_geometry(std::string const& wkt, double expected_x, double expected_y) -{ - G geometry; - bg::read_wkt(wkt, geometry); - - double s = sum<0>(bg::detail::as_range(geometry)); - BOOST_CHECK_CLOSE(s, expected_x, 0.001); - - s = sum<1>(bg::detail::as_range(geometry)); - BOOST_CHECK_CLOSE(s, expected_y, 0.001); -} - - -template -void test_all() -{ - // As-range utility should consider a geometry as a range, so - // linestring stays linestring - test_geometry >("LINESTRING(1 2,3 4)", 4, 6); - - // polygon will only be outer-ring - test_geometry >("POLYGON((1 2,3 4))", 4, 6); - test_geometry >("POLYGON((1 2,3 4),(5 6,7 8,9 10))", 4, 6); - - // the utility is useful for: - // - convex hull (holes do not count) - // - envelope (idem) -} - -int test_main(int, char* []) -{ - test_all >(); - - return 0; -} From 26d85180485f3570aa5fe5d0aebcb155460f825a Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 27 Jun 2021 20:43:28 +0200 Subject: [PATCH 04/74] Rename some of the sequence utilities. --- .../detail/convex_hull/interface.hpp | 6 +- .../detail/select_geometry_type.hpp | 11 +- .../geometries/adapted/boost_variant.hpp | 12 +- include/boost/geometry/util/sequence.hpp | 108 ++++++++---------- 4 files changed, 59 insertions(+), 78 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp index a2730c3f3..0e483e0f0 100644 --- a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp +++ b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp @@ -247,17 +247,17 @@ struct output_pointlike_less template struct output_geometry { - using polygonal_t = typename util::select_element + using polygonal_t = typename util::sequence_min_element < typename traits::geometry_types::type, output_polygonal_less >::type; - using linear_t = typename util::select_element + using linear_t = typename util::sequence_min_element < typename traits::geometry_types::type, output_linear_less >::type; - using pointlike_t = typename util::select_element + using pointlike_t = typename util::sequence_min_element < typename traits::geometry_types::type, output_pointlike_less diff --git a/include/boost/geometry/algorithms/detail/select_geometry_type.hpp b/include/boost/geometry/algorithms/detail/select_geometry_type.hpp index 235adca9f..58ec63507 100644 --- a/include/boost/geometry/algorithms/detail/select_geometry_type.hpp +++ b/include/boost/geometry/algorithms/detail/select_geometry_type.hpp @@ -92,7 +92,7 @@ template template class LessPred > struct select_geometry_type - : util::select_element + : util::sequence_min_element < typename traits::geometry_types>::type, LessPred @@ -124,10 +124,13 @@ template template class LessPred > struct select_geometry_types - : util::select_combination_element + : util::sequence_min_element < - typename geometry_types::type, - typename geometry_types::type, + typename util::sequence_combine + < + typename geometry_types::type, + typename geometry_types::type + >::type, LessPred > {}; diff --git a/include/boost/geometry/geometries/adapted/boost_variant.hpp b/include/boost/geometry/geometries/adapted/boost_variant.hpp index cc21da59c..35660c6fc 100644 --- a/include/boost/geometry/geometries/adapted/boost_variant.hpp +++ b/include/boost/geometry/geometries/adapted/boost_variant.hpp @@ -38,16 +38,6 @@ namespace boost { namespace geometry namespace detail { -template -struct parameter_pack_first_type {}; - -template -struct parameter_pack_first_type -{ - typedef T type; -}; - - template > struct boost_variant_types; @@ -78,7 +68,7 @@ template struct point_type > : point_type < - typename detail::parameter_pack_first_type + typename util::pack_front < BOOST_VARIANT_ENUM_PARAMS(T) >::type diff --git a/include/boost/geometry/util/sequence.hpp b/include/boost/geometry/util/sequence.hpp index 80e3b7b23..5bb1a5e25 100644 --- a/include/boost/geometry/util/sequence.hpp +++ b/include/boost/geometry/util/sequence.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2020, Oracle and/or its affiliates. +// Copyright (c) 2020-2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -86,6 +86,19 @@ struct sequence_element<0, std::integer_sequence> {}; +template +struct pack_front +{ + static_assert(sizeof...(Ts) > 0, "Parameter pack can not be empty."); +}; + +template +struct pack_front +{ + typedef T type; +}; + + template struct sequence_front : sequence_element<0, Sequence> @@ -142,73 +155,66 @@ struct sequence_find_if, UnaryPred> }; -// merge, type_sequence>::type is +// sequence_merge, type_sequence>::type is // type_sequence -// merge, integer_sequence>::type is +// sequence_, integer_sequence>::type is // integer_sequence template -struct merge; +struct sequence_merge; template -struct merge +struct sequence_merge { - typedef S type; + using type = S; }; template -struct merge, type_sequence> +struct sequence_merge, type_sequence> { - typedef type_sequence type; + using type = type_sequence; }; template -struct merge, std::integer_sequence> +struct sequence_merge, std::integer_sequence> { - typedef std::integer_sequence type; + using type = std::integer_sequence; }; template -struct merge +struct sequence_merge { - typedef typename merge + using type = typename sequence_merge < - typename merge::type, - typename merge::type - >::type type; + typename sequence_merge::type, + typename sequence_merge::type + >::type; }; - -// combine, type_sequence>::type is +// sequence_combine, type_sequence>::type is // type_sequence, type_sequence, // type_sequence, type_sequence> template -struct combine; +struct sequence_combine; template -struct combine, type_sequence> +struct sequence_combine, type_sequence> { template using type_sequence_t = type_sequence...>; - typedef typename merge - < - type_sequence_t... - >::type type; + using type = typename sequence_merge...>::type; }; -// combine, integer_sequence>::type is +// sequence_combine, integer_sequence>::type is // type_sequence, integer_sequence, // integer_sequence, integer_sequence> template -struct combine, std::integer_sequence> +struct sequence_combine, std::integer_sequence> { template using type_sequence_t = type_sequence...>; - typedef typename merge - < - type_sequence_t... - >::type type; + using type = typename sequence_merge...>::type; }; @@ -219,16 +225,16 @@ template template class LessPred, typename ...Ts > -struct select_pack_element; +struct pack_min_element; template < template class LessPred, typename T > -struct select_pack_element +struct pack_min_element { - typedef T type; + using type = T; }; template @@ -236,9 +242,9 @@ template template class LessPred, typename T1, typename T2 > -struct select_pack_element +struct pack_min_element { - typedef std::conditional_t::value, T1, T2> type; + using type = std::conditional_t::value, T1, T2>; }; template @@ -246,14 +252,14 @@ template template class LessPred, typename T1, typename T2, typename ...Ts > -struct select_pack_element +struct pack_min_element { - typedef typename select_pack_element + using type = typename pack_min_element < LessPred, - typename select_pack_element::type, - typename select_pack_element::type - >::type type; + typename pack_min_element::type, + typename pack_min_element::type + >::type; }; @@ -264,34 +270,16 @@ template typename Sequence, template class LessPred > -struct select_element; +struct sequence_min_element; template < typename ...Ts, template class LessPred > -struct select_element, LessPred> +struct sequence_min_element, LessPred> { - typedef typename select_pack_element::type type; -}; - - -// Selects least pair sequence of elements from a parameter pack based on -// LessPred, xxx_sequence>::value comparison -template -< - typename Sequence1, - typename Sequence2, - template class LessPred -> -struct select_combination_element -{ - typedef typename select_element - < - typename combine::type, - LessPred - >::type type; + using type = typename pack_min_element::type; }; From 8fddb60cdc39686357ad5560b9738f2f795d76ee Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 28 Jun 2021 00:29:00 +0200 Subject: [PATCH 05/74] Add support for output DynamicGeometry in convex_hull(). --- .../detail/convex_hull/interface.hpp | 66 ++++++++++++++----- .../detail/select_geometry_type.hpp | 12 ++-- .../convex_hull/test_convex_hull.hpp | 7 ++ 3 files changed, 63 insertions(+), 22 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp index 0e483e0f0..c7d169242 100644 --- a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp +++ b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp @@ -152,7 +152,7 @@ struct output_geometry template struct output_geometry { - output_geometry(OutputGeometry & out) : m_out(out) {} + explicit output_geometry(OutputGeometry & out) : m_out(out) {} OutputGeometry & range() { return m_out; } template void move_to_out(Strategy const& ) {} @@ -163,7 +163,7 @@ private: template struct output_geometry { - output_geometry(OutputGeometry & out) : m_out(out) {} + explicit output_geometry(OutputGeometry & out) : m_out(out) {} OutputGeometry & range() { return m_out; } template void move_to_out(Strategy const& ) {} @@ -174,7 +174,7 @@ private: template struct output_geometry { - output_geometry(OutputGeometry & out) : m_out(out) {} + explicit output_geometry(OutputGeometry & out) : m_out(out) {} decltype(auto) range() { return exterior_ring(m_out); } template void move_to_out(Strategy const& ) {} @@ -185,7 +185,7 @@ private: template struct output_geometry { - output_geometry(OutputGeometry & out) : m_out(out) {} + explicit output_geometry(OutputGeometry & out) : m_out(out) {} decltype(auto) range() { return exterior_ring(m_polygon); } template void move_to_out(Strategy const& ) @@ -244,8 +244,26 @@ struct output_pointlike_less static const bool value = priority::value < priority::value; }; -template -struct output_geometry +struct move_emplace_back_policy +{ + template + static inline void apply(Geometry & g, OutputGeometry & out) + { + range::emplace_back(out, std::move(g)); + } +}; + +struct move_assign_policy +{ + template + static inline void apply(Geometry & g, OutputGeometry & out) + { + out = std::move(g); + } +}; + +template +struct output_geometry_dg_or_gc { using polygonal_t = typename util::sequence_min_element < @@ -265,18 +283,18 @@ struct output_geometry // select_element may define different kind of geometry than the one that is desired BOOST_GEOMETRY_STATIC_ASSERT(util::is_polygonal::value, - "It must be possible to store polygonal geometry in GeometryCollection.", polygonal_t); + "It must be possible to store polygonal geometry in OutputGeometry.", polygonal_t); BOOST_GEOMETRY_STATIC_ASSERT(util::is_linear::value, - "It must be possible to store linear geometry in GeometryCollection.", linear_t); + "It must be possible to store linear geometry in OutputGeometry.", linear_t); BOOST_GEOMETRY_STATIC_ASSERT(util::is_pointlike::value, - "It must be possible to store pointlike geometry in GeometryCollection.", pointlike_t); + "It must be possible to store pointlike geometry in OutputGeometry.", pointlike_t); - output_geometry(OutputGeometry & out) + explicit output_geometry_dg_or_gc(OutputGeometry & out) : m_out(out), m_wrapper(m_polygonal) {} decltype(auto) range() { return m_wrapper.range(); } - + template void move_to_out(Strategy const& strategy) { @@ -287,7 +305,7 @@ struct output_geometry if (size > minimum_ring_size::value) { m_wrapper.move_to_out(strategy); - range::emplace_back(m_out, std::move(m_polygonal)); + MovePolicy::apply(m_polygonal, m_out); } else // size == 3 || size == 4 { @@ -295,18 +313,18 @@ struct output_geometry { pointlike_t pointlike; move_to_pointlike(out_range, pointlike); - range::emplace_back(m_out, std::move(pointlike)); + MovePolicy::apply(pointlike, m_out); } else if (detail::equals::equals_point_point(range::front(out_range), range::at(out_range, 2), strategy)) { linear_t linear; move_to_linear(out_range, linear); - range::emplace_back(m_out, std::move(linear)); + MovePolicy::apply(linear, m_out); } else { m_wrapper.move_to_out(strategy); - range::emplace_back(m_out, std::move(m_polygonal)); + MovePolicy::apply(m_polygonal, m_out); } } } @@ -348,6 +366,24 @@ private: output_geometry m_wrapper; }; +template +struct output_geometry + : output_geometry_dg_or_gc +{ + explicit output_geometry(OutputGeometry & out) + : output_geometry_dg_or_gc(out) + {} +}; + +template +struct output_geometry + : output_geometry_dg_or_gc +{ + explicit output_geometry(OutputGeometry & out) + : output_geometry_dg_or_gc(out) + {} +}; + }} // namespace detail::convex_hull #endif // DOXYGEN_NO_DETAIL diff --git a/include/boost/geometry/algorithms/detail/select_geometry_type.hpp b/include/boost/geometry/algorithms/detail/select_geometry_type.hpp index 58ec63507..5592fa5c4 100644 --- a/include/boost/geometry/algorithms/detail/select_geometry_type.hpp +++ b/include/boost/geometry/algorithms/detail/select_geometry_type.hpp @@ -31,13 +31,6 @@ struct first_geometry_type using type = Geometry; }; -template -struct first_geometry_type -{ - BOOST_GEOMETRY_STATIC_ASSERT_FALSE("Not implemented for this Geometry", - Geometry, dynamic_geometry_tag); -}; - template struct first_geometry_type { @@ -55,6 +48,11 @@ struct first_geometry_type >::type; }; +template +struct first_geometry_type + : first_geometry_type +{}; + template < diff --git a/test/algorithms/convex_hull/test_convex_hull.hpp b/test/algorithms/convex_hull/test_convex_hull.hpp index e77584072..34720a27e 100644 --- a/test/algorithms/convex_hull/test_convex_hull.hpp +++ b/test/algorithms/convex_hull/test_convex_hull.hpp @@ -152,8 +152,15 @@ struct test_convex_hull using point_t = typename bg::point_type::type; using var_t = boost::variant, point_t>; using gc_t = bg::model::geometry_collection; + + var_t var; + bg::convex_hull(geometry, var, Strategy()); + gc_t gc; bg::convex_hull(geometry, gc, Strategy()); + + BOOST_CHECK(var.which() == gc[0].which()); + if (bg::detail::equals::equals_point_point(hull.outer()[0], hull.outer()[1], Strategy())) BOOST_CHECK(gc[0].which() == 2); // GC stores point else if (bg::detail::equals::equals_point_point(hull.outer()[0], hull.outer()[2], Strategy())) From 67610fcc29d631114958af0cfd87f201b0711e4e Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 28 Jun 2021 23:43:32 +0200 Subject: [PATCH 06/74] Refactor convex_hull() output geometry handling. Rename input geometry proxy. Add several enable_if_xxx traits. --- .../detail/convex_hull/graham_andrew.hpp | 26 +- .../detail/convex_hull/interface.hpp | 488 ++++++++---------- include/boost/geometry/util/type_traits.hpp | 41 ++ 3 files changed, 280 insertions(+), 275 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/convex_hull/graham_andrew.hpp b/include/boost/geometry/algorithms/detail/convex_hull/graham_andrew.hpp index 7f3d61567..9e59927f5 100644 --- a/include/boost/geometry/algorithms/detail/convex_hull/graham_andrew.hpp +++ b/include/boost/geometry/algorithms/detail/convex_hull/graham_andrew.hpp @@ -46,13 +46,13 @@ namespace detail { namespace convex_hull // TODO: All of the copies could be avoided if this function stored pointers to points. // But would it be possible considering that a range can return proxy reference? -template -inline void get_extremes(Ranges const& ranges, +template +inline void get_extremes(InputProxy const& in_proxy, Point& left, Point& right, Less const& less) { bool first = true; - ranges.for_each_range([&](auto const& range) + in_proxy.for_each_range([&](auto const& range) { if (boost::empty(range)) { @@ -108,13 +108,13 @@ inline void get_extremes(Ranges const& ranges, } -template -inline void assign_ranges(Ranges const& ranges, +template +inline void assign_ranges(InputProxy const& in_proxy, Point const& most_left, Point const& most_right, Container& lower_points, Container& upper_points, SideStrategy const& side) { - ranges.for_each_range([&](auto const& range) + in_proxy.for_each_range([&](auto const& range) { // Put points in one of the two output sequences for (auto it = boost::begin(range); it != boost::end(range); ++it) @@ -161,12 +161,12 @@ class graham_andrew }; public: - template - static void apply(InputRanges const& ranges, OutputRing & out_ring, Strategy& strategy) + template + static void apply(InputProxy const& in_proxy, OutputRing & out_ring, Strategy& strategy) { partitions state; - apply(ranges, state, strategy); + apply(in_proxy, state, strategy); result(state, range::back_inserter(out_ring), @@ -175,8 +175,8 @@ public: } private: - template - static void apply(InputRanges const& ranges, partitions& state, Strategy& strategy) + template + static void apply(InputProxy const& in_proxy, partitions& state, Strategy& strategy) { // First pass. // Get min/max (in most cases left / right) points @@ -195,7 +195,7 @@ private: // TODO: User-defined CS-specific less-compare geometry::less less; - detail::convex_hull::get_extremes(ranges, most_left, most_right, less); + detail::convex_hull::get_extremes(in_proxy, most_left, most_right, less); container_type lower_points, upper_points; @@ -204,7 +204,7 @@ private: // Bounding left/right points // Second pass, now that extremes are found, assign all points // in either lower, either upper - detail::convex_hull::assign_ranges(ranges, most_left, most_right, + detail::convex_hull::assign_ranges(in_proxy, most_left, most_right, lower_points, upper_points, side_strategy); diff --git a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp index c7d169242..c7823b1b8 100644 --- a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp +++ b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp @@ -68,9 +68,9 @@ namespace detail { namespace convex_hull // Abstraction representing ranges/rings of a geometry template -struct geometry_ranges +struct input_geometry_proxy { - geometry_ranges(Geometry const& geometry) + input_geometry_proxy(Geometry const& geometry) : m_geometry(geometry) {} @@ -86,9 +86,9 @@ struct geometry_ranges // Abstraction representing ranges/rings of subgeometries of geometry collection // with boxes converted to rings template -struct geometry_collection_ranges +struct input_geometry_collection_proxy { - geometry_collection_ranges(Geometry const& geometry, BoxRings const& box_rings) + input_geometry_collection_proxy(Geometry const& geometry, BoxRings const& box_rings) : m_geometry(geometry) , m_box_rings(box_rings) {} @@ -140,66 +140,7 @@ struct default_strategy {}; -// Wrapper for output geometry. It contains reference to OutputGeometry and may contain -// a temporary geometry which is moved to the output at the end of the algorithm. -template ::type> -struct output_geometry -{ - BOOST_GEOMETRY_STATIC_ASSERT_FALSE("This OutputGeometry is not supported.", OutputGeometry, Tag); -}; - -// For backward compatibility -template -struct output_geometry -{ - explicit output_geometry(OutputGeometry & out) : m_out(out) {} - OutputGeometry & range() { return m_out; } - template - void move_to_out(Strategy const& ) {} -private: - OutputGeometry & m_out; -}; - -template -struct output_geometry -{ - explicit output_geometry(OutputGeometry & out) : m_out(out) {} - OutputGeometry & range() { return m_out; } - template - void move_to_out(Strategy const& ) {} -private: - OutputGeometry & m_out; -}; - -template -struct output_geometry -{ - explicit output_geometry(OutputGeometry & out) : m_out(out) {} - decltype(auto) range() { return exterior_ring(m_out); } - template - void move_to_out(Strategy const& ) {} -private: - OutputGeometry & m_out; -}; - -template -struct output_geometry -{ - explicit output_geometry(OutputGeometry & out) : m_out(out) {} - decltype(auto) range() { return exterior_ring(m_polygon); } - template - void move_to_out(Strategy const& ) - { - if (! boost::empty(exterior_ring(m_polygon))) - { - range::push_back(m_out, std::move(m_polygon)); - } - } -private: - OutputGeometry & m_out; - typename boost::range_value::type m_polygon; -}; - +// Utilities for output GC and DG template struct output_polygonal_less { @@ -244,41 +185,186 @@ struct output_pointlike_less static const bool value = priority::value < priority::value; }; -struct move_emplace_back_policy + +}} // namespace detail::convex_hull +#endif // DOXYGEN_NO_DETAIL + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch { - template - static inline void apply(Geometry & g, OutputGeometry & out) + + +template +< + typename Geometry, + typename Tag = typename tag::type +> +struct convex_hull +{ + template + static inline void apply(Geometry const& geometry, + OutputGeometry& out, + Strategy const& strategy) { - range::emplace_back(out, std::move(g)); + detail::convex_hull::input_geometry_proxy in_proxy(geometry); + detail::convex_hull::graham_andrew + < + typename point_type::type + >::apply(in_proxy, out, strategy); } }; -struct move_assign_policy + +// A hull for boxes is trivial. Any strategy is (currently) skipped. +// TODO: This is not correct in spherical and geographic CS. +template +struct convex_hull { - template - static inline void apply(Geometry & g, OutputGeometry & out) + template + static inline void apply(Box const& box, + OutputGeometry& out, + Strategy const& strategy) { - out = std::move(g); + static bool const Close + = geometry::closure::value == closed; + static bool const Reverse + = geometry::point_order::value == counterclockwise; + + std::array::type, 4> arr; + // TODO: This assigns only 2d cooridnates! + // And it is also used in box_view<>! + geometry::detail::assign_box_corners_oriented(box, arr); + + std::move(arr.begin(), arr.end(), range::back_inserter(out)); + if (BOOST_GEOMETRY_CONDITION(Close)) + { + range::push_back(out, range::front(out)); + } } }; -template -struct output_geometry_dg_or_gc + +template +struct convex_hull +{ + template + static inline void apply(GeometryCollection const& geometry, + OutputGeometry& out, + Strategy const& strategy) + { + // Assuming that single point_type is used by the GeometryCollection + using subgeometry_type = typename detail::first_geometry_type::type; + using point_type = typename geometry::point_type::type; + using ring_type = model::ring; + + // Calculate box rings once + std::vector box_rings; + detail::visit_breadth_first([&](auto const& g) + { + add_ring_for_box(box_rings, g, strategy); + return true; + }, geometry); + + detail::convex_hull::input_geometry_collection_proxy + < + GeometryCollection, std::vector + > in_proxy(geometry, box_rings); + + detail::convex_hull::graham_andrew + < + point_type + >::apply(in_proxy, out, strategy); + } + +private: + template + < + typename Ring, typename SubGeometry, typename Strategy, + std::enable_if_t::value, int> = 0 + > + static inline void add_ring_for_box(std::vector & rings, SubGeometry const& box, + Strategy const& strategy) + { + Ring ring; + convex_hull::apply(box, ring, strategy); + rings.push_back(std::move(ring)); + } + template + < + typename Ring, typename SubGeometry, typename Strategy, + std::enable_if_t::value, int> = 0 + > + static inline void add_ring_for_box(std::vector & , SubGeometry const& , + Strategy const& ) + {} +}; + + +template ::type> +struct convex_hull_out +{ + BOOST_GEOMETRY_STATIC_ASSERT_FALSE("This OutputGeometry is not supported.", OutputGeometry, Tag); +}; + +template +struct convex_hull_out +{ + template + static inline void apply(Geometry const& geometry, + OutputGeometry& out, + Strategies const& strategies) + { + dispatch::convex_hull::apply(geometry, out, strategies); + } +}; + +template +struct convex_hull_out +{ + template + static inline void apply(Geometry const& geometry, + OutputGeometry& out, + Strategies const& strategies) + { + auto&& ring = exterior_ring(out); + dispatch::convex_hull::apply(geometry, ring, strategies); + } +}; + +template +struct convex_hull_out +{ + template + static inline void apply(Geometry const& geometry, + OutputGeometry& out, + Strategies const& strategies) + { + typename boost::range_value::type polygon; + auto&& ring = exterior_ring(polygon); + dispatch::convex_hull::apply(geometry, ring, strategies); + // Empty input is checked so the output shouldn't be empty + range::push_back(out, std::move(polygon)); + } +}; + +template +struct convex_hull_out { using polygonal_t = typename util::sequence_min_element < typename traits::geometry_types::type, - output_polygonal_less + detail::convex_hull::output_polygonal_less >::type; using linear_t = typename util::sequence_min_element < typename traits::geometry_types::type, - output_linear_less + detail::convex_hull::output_linear_less >::type; using pointlike_t = typename util::sequence_min_element < typename traits::geometry_types::type, - output_pointlike_less + detail::convex_hull::output_pointlike_less >::type; // select_element may define different kind of geometry than the one that is desired @@ -289,48 +375,55 @@ struct output_geometry_dg_or_gc BOOST_GEOMETRY_STATIC_ASSERT(util::is_pointlike::value, "It must be possible to store pointlike geometry in OutputGeometry.", pointlike_t); - explicit output_geometry_dg_or_gc(OutputGeometry & out) - : m_out(out), m_wrapper(m_polygonal) - {} - - decltype(auto) range() { return m_wrapper.range(); } - - template - void move_to_out(Strategy const& strategy) + template + static inline void apply(Geometry const& geometry, + OutputGeometry& out, + Strategies const& strategies) { - auto&& out_range = m_wrapper.range(); - if (! boost::empty(out_range)) + polygonal_t polygonal; + convex_hull_out::apply(geometry, polygonal, strategies); + // Empty input is checked so the output shouldn't be empty + auto&& out_ring = ring(polygonal); + + if (boost::size(out_ring) == detail::minimum_ring_size::value) { - auto size = boost::size(out_range); - if (size > minimum_ring_size::value) + using detail::equals::equals_point_point; + if (equals_point_point(range::front(out_ring), range::at(out_ring, 1), strategies)) { - m_wrapper.move_to_out(strategy); - MovePolicy::apply(m_polygonal, m_out); + pointlike_t pointlike; + move_to_pointlike(out_ring, pointlike); + move_to_out(pointlike, out); + return; } - else // size == 3 || size == 4 + if (equals_point_point(range::front(out_ring), range::at(out_ring, 2), strategies)) { - if (detail::equals::equals_point_point(range::front(out_range), range::at(out_range, 1), strategy)) - { - pointlike_t pointlike; - move_to_pointlike(out_range, pointlike); - MovePolicy::apply(pointlike, m_out); - } - else if (detail::equals::equals_point_point(range::front(out_range), range::at(out_range, 2), strategy)) - { - linear_t linear; - move_to_linear(out_range, linear); - MovePolicy::apply(linear, m_out); - } - else - { - m_wrapper.move_to_out(strategy); - MovePolicy::apply(m_polygonal, m_out); - } + linear_t linear; + move_to_linear(out_ring, linear); + move_to_out(linear, out); + return; } } + + move_to_out(polygonal, out); } private: + template = 0> + static decltype(auto) ring(Polygonal const& polygonal) + { + return polygonal; + } + template = 0> + static decltype(auto) ring(Polygonal const& polygonal) + { + return exterior_ring(polygonal); + } + template = 0> + static decltype(auto) ring(Polygonal const& polygonal) + { + return exterior_ring(range::front(polygonal)); + } + template = 0> static void move_to_linear(Range & out_range, Linear & seg) { @@ -361,167 +454,38 @@ private: range::push_back(mpt, std::move(range::front(out_range))); } - OutputGeometry & m_out; - polygonal_t m_polygonal; - output_geometry m_wrapper; -}; - -template -struct output_geometry - : output_geometry_dg_or_gc -{ - explicit output_geometry(OutputGeometry & out) - : output_geometry_dg_or_gc(out) - {} -}; - -template -struct output_geometry - : output_geometry_dg_or_gc -{ - explicit output_geometry(OutputGeometry & out) - : output_geometry_dg_or_gc(out) - {} -}; - - -}} // namespace detail::convex_hull -#endif // DOXYGEN_NO_DETAIL - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - -template -< - typename Geometry, - typename Tag = typename tag::type -> -struct convex_hull -{ - template - static inline void apply(Geometry const& geometry, - OutputGeometry& out, - Strategy const& strategy) - { - detail::convex_hull::geometry_ranges ranges(geometry); - - detail::convex_hull::output_geometry out_wrapper(out); - // NOTE: A variable is created here because this can be a proxy range - // and back_insert_iterator<> can store a pointer to it. - auto&& out_range = out_wrapper.range(); - - detail::convex_hull::graham_andrew - < - typename point_type::type - >::apply(ranges, out_range, strategy); - - out_wrapper.move_to_out(strategy); - } -}; - - -// A hull for boxes is trivial. Any strategy is (currently) skipped. -// TODO: This is not correct in spherical and geographic CS. -template -struct convex_hull -{ - template - static inline void apply(Box const& box, - OutputGeometry& out, - Strategy const& strategy) - { - detail::convex_hull::output_geometry out_wrapper(out); - // NOTE: A variable is created here because this can be a proxy range - // and back_insert_iterator<> can store a pointer to it. - auto&& out_range = out_wrapper.range(); - - using out_range_t = std::remove_reference_t; - static bool const Close - = geometry::closure::value == closed; - static bool const Reverse - = geometry::point_order::value == counterclockwise; - - std::array::type, 4> arr; - // TODO: This assigns only 2d cooridnates! - // And it is also used in box_view<>! - geometry::detail::assign_box_corners_oriented(box, arr); - - std::move(arr.begin(), arr.end(), range::back_inserter(out_range)); - if (BOOST_GEOMETRY_CONDITION(Close)) - { - range::push_back(out_range, range::front(out_range)); - } - - out_wrapper.move_to_out(strategy); - } -}; - - -template -struct convex_hull -{ - template - static inline void apply(GeometryCollection const& geometry, - OutputGeometry& out, - Strategy const& strategy) - { - // Assuming that single point_type is used by the GeometryCollection - using subgeometry_type = typename detail::first_geometry_type::type; - using point_type = typename geometry::point_type::type; - using ring_type = model::ring; - - // Calculate box rings once - std::vector box_rings; - detail::visit_breadth_first([&](auto const& g) - { - add_ring_for_box(box_rings, g, strategy); - return true; - }, geometry); - - detail::convex_hull::geometry_collection_ranges - < - GeometryCollection, std::vector - > ranges(geometry, box_rings); - - detail::convex_hull::output_geometry out_wrapper(out); - // NOTE: A variable is created here because this can be a proxy range - // and back_insert_iterator<> can store a pointer to it. - auto&& out_range = out_wrapper.range(); - - detail::convex_hull::graham_andrew - < - point_type - >::apply(ranges, out_range, strategy); - - out_wrapper.move_to_out(strategy); - } - -private: template < - typename Ring, typename SubGeometry, typename Strategy, - std::enable_if_t::value, int> = 0 + typename Geometry, typename OutputGeometry_, + util::enable_if_geometry_collection_t = 0 > - static inline void add_ring_for_box(std::vector & rings, SubGeometry const& box, - Strategy const& strategy) + static void move_to_out(Geometry & g, OutputGeometry_ & out) { - Ring ring; - convex_hull::apply(box, ring, strategy); - rings.push_back(std::move(ring)); + range::emplace_back(out, std::move(g)); } template < - typename Ring, typename SubGeometry, typename Strategy, - std::enable_if_t::value, int> = 0 + typename Geometry, typename OutputGeometry_, + util::enable_if_dynamic_geometry_t = 0 > - static inline void add_ring_for_box(std::vector & , SubGeometry const& , - Strategy const& ) - {} + static void move_to_out(Geometry & g, OutputGeometry_ & out) + { + out = std::move(g); + } }; +template +struct convex_hull_out + : convex_hull_out +{}; + + +// For backward compatibility +template +struct convex_hull_out + : convex_hull_out +{}; + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH @@ -537,7 +501,7 @@ struct convex_hull OutputGeometry& out, Strategies const& strategies) { - dispatch::convex_hull::apply(geometry, out, strategies); + dispatch::convex_hull_out::apply(geometry, out, strategies); } }; @@ -554,7 +518,7 @@ struct convex_hull Geometry >::type; - dispatch::convex_hull::apply(geometry, out, strategy_type()); + dispatch::convex_hull_out::apply(geometry, out, strategy_type()); } }; diff --git a/include/boost/geometry/util/type_traits.hpp b/include/boost/geometry/util/type_traits.hpp index 7ad4c71bc..c58b5bad0 100644 --- a/include/boost/geometry/util/type_traits.hpp +++ b/include/boost/geometry/util/type_traits.hpp @@ -225,6 +225,30 @@ struct enable_if_box template using enable_if_box_t = typename enable_if_box::type; +template +struct enable_if_ring + : std::enable_if::value, T> +{}; + +template +using enable_if_ring_t = typename enable_if_ring::type; + +template +struct enable_if_polygon + : std::enable_if::value, T> +{}; + +template +using enable_if_polygon_t = typename enable_if_polygon::type; + +template +struct enable_if_multi_polygon + : std::enable_if::value, T> +{}; + +template +using enable_if_multi_polygon_t = typename enable_if_multi_polygon::type; + template struct enable_if_polygonal @@ -253,6 +277,23 @@ template using enable_if_polysegmental_t = typename enable_if_polysegmental::type; +template +struct enable_if_dynamic_geometry + : std::enable_if::value, T> +{}; + +template +using enable_if_dynamic_geometry_t = typename enable_if_dynamic_geometry::type; + +template +struct enable_if_geometry_collection + : std::enable_if::value, T> +{}; + +template +using enable_if_geometry_collection_t = typename enable_if_geometry_collection::type; + + } // namespace util From 673f14c7961f6ceb4993cd4f90e238356c3242b7 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 30 Jun 2021 02:07:49 +0200 Subject: [PATCH 07/74] Add support for DG/GC in correct, correct_closure, is_convex and reverse. Refactor the algorithms together with detail::multi_modify. Add tests for is_convex and correct. --- include/boost/geometry/algorithms/correct.hpp | 266 +++++++++--------- .../geometry/algorithms/correct_closure.hpp | 110 ++++---- .../algorithms/detail/multi_modify.hpp | 21 +- .../boost/geometry/algorithms/is_convex.hpp | 108 ++++--- include/boost/geometry/algorithms/reverse.hpp | 71 +++-- .../extensions/algorithms/remove_holes_if.hpp | 10 +- test/algorithms/is_convex.cpp | 42 ++- test/algorithms/test_correct.hpp | 17 +- 8 files changed, 349 insertions(+), 296 deletions(-) diff --git a/include/boost/geometry/algorithms/correct.hpp b/include/boost/geometry/algorithms/correct.hpp index 3c338916b..9d1f246a6 100644 --- a/include/boost/geometry/algorithms/correct.hpp +++ b/include/boost/geometry/algorithms/correct.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2017-2020. -// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -28,12 +28,11 @@ #include #include -#include -#include -#include - +#include #include #include +#include +#include #include #include @@ -42,12 +41,18 @@ #include #include #include +#include +#include // For backward compatibility #include -#include -#include -#include +#include +#include +#include +#include + +#include + namespace boost { namespace geometry { @@ -62,92 +67,56 @@ namespace boost { namespace geometry namespace detail { namespace correct { -template struct correct_nop { - template + template static inline void apply(Geometry& , Strategy const& ) {} }; -template -struct correct_box_loop -{ - typedef typename coordinate_type::type coordinate_type; - - static inline void apply(Box& box) - { - if (get(box) > get(box)) - { - // Swap the coordinates - coordinate_type max_value = get(box); - coordinate_type min_value = get(box); - set(box, min_value); - set(box, max_value); - } - - correct_box_loop - < - Box, Dimension + 1, DimensionCount - >::apply(box); - } -}; - - - -template -struct correct_box_loop -{ - static inline void apply(Box& ) - {} - -}; - - // Correct a box: make min/max correct -template struct correct_box { - template + template static inline void apply(Box& box, Strategy const& ) { + using coordinate_type = typename geometry::coordinate_type::type; + // Currently only for Cartesian coordinates // (or spherical without crossing dateline) // Future version: adapt using strategies - correct_box_loop - < - Box, 0, dimension::type::value - >::apply(box); + detail::for_each_dimension([&](auto dimension) + { + if (get(box) > get(box)) + { + // Swap the coordinates + coordinate_type max_value = get(box); + coordinate_type min_value = get(box); + set(box, min_value); + set(box, max_value); + } + }); } }; // Close a ring, if not closed -template class Predicate> +template > struct correct_ring { - typedef typename point_type::type point_type; - typedef typename coordinate_type::type coordinate_type; - - template + template static inline void apply(Ring& r, Strategy const& strategy) { // Correct closure if necessary - detail::correct_closure::close_or_open_ring::apply(r); + detail::correct_closure::close_or_open_ring::apply(r); + + // NOTE: calculate_point_order should probably be used here instead. // Check area - typedef typename area_result::type area_result_type; - Predicate predicate; - area_result_type const zero = 0; - if (predicate(detail::area::ring_area::apply( - r, - // TEMP - in the future (umbrella) strategy will be passed - geometry::strategies::area::services::strategy_converter - < - Strategy - >::get(strategy)), - zero)) + using area_t = typename area_result::type; + area_t const zero = 0; + if (Predicate()(detail::area::ring_area::apply(r, strategy), zero)) { std::reverse(boost::begin(r), boost::end(r)); } @@ -156,30 +125,18 @@ struct correct_ring // Correct a polygon: normalizes all rings, sets outer ring clockwise, sets all // inner rings counter clockwise (or vice versa depending on orientation) -template struct correct_polygon { - typedef typename ring_type::type ring_type; - - template + template static inline void apply(Polygon& poly, Strategy const& strategy) { - correct_ring - < - ring_type, - std::less - >::apply(exterior_ring(poly), strategy); + correct_ring>::apply(exterior_ring(poly), strategy); - typename interior_return_type::type - rings = interior_rings(poly); - for (typename detail::interior_iterator::type - it = boost::begin(rings); it != boost::end(rings); ++it) + auto&& rings = interior_rings(poly); + auto const end = boost::end(rings); + for (auto it = boost::begin(rings); it != end; ++it) { - correct_ring - < - ring_type, - std::greater - >::apply(*it, strategy); + correct_ring>::apply(*it, strategy); } } }; @@ -199,62 +156,51 @@ struct correct: not_implemented template struct correct - : detail::correct::correct_nop + : detail::correct::correct_nop {}; template struct correct - : detail::correct::correct_nop + : detail::correct::correct_nop {}; template struct correct - : detail::correct::correct_nop + : detail::correct::correct_nop {}; template struct correct - : detail::correct::correct_box + : detail::correct::correct_box {}; template struct correct - : detail::correct::correct_ring - < - Ring, - std::less - > + : detail::correct::correct_ring<> {}; template struct correct - : detail::correct::correct_polygon + : detail::correct::correct_polygon {}; template struct correct - : detail::correct::correct_nop + : detail::correct::correct_nop {}; template struct correct - : detail::correct::correct_nop + : detail::correct::correct_nop {}; template struct correct - : detail::multi_modify - < - Geometry, - detail::correct::correct_polygon - < - typename boost::range_value::type - > - > + : detail::multi_modify {}; @@ -262,45 +208,96 @@ struct correct #endif // DOXYGEN_NO_DISPATCH -namespace resolve_variant { +namespace resolve_strategy +{ -template +template +< + typename Strategy, + bool IsUmbrella = strategies::detail::is_umbrella_strategy::value +> +struct correct +{ + template + static inline void apply(Geometry& geometry, Strategy const& strategy) + { + dispatch::correct::apply(geometry, strategy); + } +}; + +template +struct correct +{ + template + static inline void apply(Geometry& geometry, Strategy const& strategy) + { + // NOTE: calculate_point_order strategy should probably be used here instead. + using geometry::strategies::area::services::strategy_converter; + dispatch::correct::apply(geometry, strategy_converter::get(strategy)); + } +}; + +template <> +struct correct +{ + template + static inline void apply(Geometry& geometry, default_strategy const& ) + { + // NOTE: calculate_point_order strategy should probably be used here instead. + using strategy_type = typename strategies::area::services::default_strategy + < + Geometry + >::type; + dispatch::correct::apply(geometry, strategy_type()); + } +}; + +} // namespace resolve_strategy + + +namespace resolve_dynamic +{ + +template ::type> struct correct { template static inline void apply(Geometry& geometry, Strategy const& strategy) { - concepts::check(); - dispatch::correct::apply(geometry, strategy); + concepts::check(); + resolve_strategy::correct::apply(geometry, strategy); } }; -template -struct correct > +template +struct correct { template - struct visitor: boost::static_visitor + static inline void apply(Geometry& geometry, Strategy const& strategy) { - Strategy const& m_strategy; - - visitor(Strategy const& strategy): m_strategy(strategy) {} - - template - void operator()(Geometry& geometry) const + traits::visit::apply([&](auto & g) { - correct::apply(geometry, m_strategy); - } - }; - - template - static inline void - apply(boost::variant& geometry, Strategy const& strategy) - { - boost::apply_visitor(visitor(strategy), geometry); + correct>::apply(g, strategy); + }, geometry); } }; -} // namespace resolve_variant +template +struct correct +{ + template + static inline void apply(Geometry& geometry, Strategy const& strategy) + { + detail::visit_breadth_first([&](auto & g) + { + correct>::apply(g, strategy); + return true; + }, geometry); + } +}; + + +} // namespace resolve_dynamic /*! @@ -318,14 +315,7 @@ struct correct > template inline void correct(Geometry& geometry) { - typedef typename point_type::type point_type; - - typedef typename strategy::area::services::default_strategy - < - typename cs_tag::type - >::type strategy_type; - - resolve_variant::correct::apply(geometry, strategy_type()); + resolve_dynamic::correct::apply(geometry, default_strategy()); } /*! @@ -347,7 +337,7 @@ inline void correct(Geometry& geometry) template inline void correct(Geometry& geometry, Strategy const& strategy) { - resolve_variant::correct::apply(geometry, strategy); + resolve_dynamic::correct::apply(geometry, strategy); } #if defined(_MSC_VER) diff --git a/include/boost/geometry/algorithms/correct_closure.hpp b/include/boost/geometry/algorithms/correct_closure.hpp index 4160f256f..60b8beef5 100644 --- a/include/boost/geometry/algorithms/correct_closure.hpp +++ b/include/boost/geometry/algorithms/correct_closure.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2017 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 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, @@ -15,16 +15,9 @@ #include -#include -#include -#include -#include - -#include -#include -#include - #include +#include +#include #include #include @@ -32,10 +25,11 @@ #include #include +#include #include -#include -#include +#include +#include namespace boost { namespace geometry { @@ -50,59 +44,55 @@ namespace boost { namespace geometry namespace detail { namespace correct_closure { -template struct nop { + template static inline void apply(Geometry& ) {} }; - // Close a ring, if not closed, or open it -template struct close_or_open_ring { + template static inline void apply(Ring& r) { - if (boost::size(r) <= 2) + auto size = boost::size(r); + if (size <= 2) { return; } - bool const disjoint = geometry::disjoint(*boost::begin(r), - *(boost::end(r) - 1)); - closure_selector const s = geometry::closure::value; + // TODO: This requires relate(pt, pt) strategy + bool const disjoint = geometry::disjoint(*boost::begin(r), *(boost::end(r) - 1)); + closure_selector const closure = geometry::closure::value; - if (disjoint && s == closed) + if (disjoint && closure == closed) { // Close it by adding first point geometry::append(r, *boost::begin(r)); } - else if (! disjoint && s != closed) + else if (! disjoint && closure == open) { // Open it by removing last point - geometry::traits::resize::apply(r, boost::size(r) - 1); + range::resize(r, size - 1); } } }; // Close/open exterior ring and all its interior rings -template struct close_or_open_polygon { - typedef typename ring_type::type ring_type; - + template static inline void apply(Polygon& poly) { - close_or_open_ring::apply(exterior_ring(poly)); + close_or_open_ring::apply(exterior_ring(poly)); - typename interior_return_type::type - rings = interior_rings(poly); - - for (typename detail::interior_iterator::type - it = boost::begin(rings); it != boost::end(rings); ++it) + auto&& rings = interior_rings(poly); + auto const end = boost::end(rings); + for (auto it = boost::begin(rings); it != end; ++it) { - close_or_open_ring::apply(*it); + close_or_open_ring::apply(*it); } } }; @@ -121,45 +111,45 @@ struct correct_closure: not_implemented template struct correct_closure - : detail::correct_closure::nop + : detail::correct_closure::nop {}; template struct correct_closure - : detail::correct_closure::nop + : detail::correct_closure::nop {}; template struct correct_closure - : detail::correct_closure::nop + : detail::correct_closure::nop {}; template struct correct_closure - : detail::correct_closure::nop + : detail::correct_closure::nop {}; template struct correct_closure - : detail::correct_closure::close_or_open_ring + : detail::correct_closure::close_or_open_ring {}; template struct correct_closure - : detail::correct_closure::close_or_open_polygon + : detail::correct_closure::close_or_open_polygon {}; template struct correct_closure - : detail::correct_closure::nop + : detail::correct_closure::nop {}; template struct correct_closure - : detail::correct_closure::nop + : detail::correct_closure::nop {}; @@ -167,11 +157,7 @@ template struct correct_closure : detail::multi_modify < - Geometry, detail::correct_closure::close_or_open_polygon - < - typename boost::range_value::type - > > {}; @@ -183,7 +169,7 @@ struct correct_closure namespace resolve_variant { -template +template ::type> struct correct_closure { static inline void apply(Geometry& geometry) @@ -193,29 +179,37 @@ struct correct_closure } }; -template -struct correct_closure > +template +struct correct_closure { - struct visitor: boost::static_visitor + static void apply(Geometry& geometry) { - template - void operator()(Geometry& geometry) const + traits::visit::apply([](auto & g) { - correct_closure::apply(geometry); - } - }; + correct_closure>::apply(g); + }, geometry); + } +}; - static inline void - apply(boost::variant& geometry) +template +struct correct_closure +{ + static void apply(Geometry& geometry) { - visitor vis; - boost::apply_visitor(vis, geometry); + detail::visit_breadth_first([](auto & g) + { + correct_closure>::apply(g); + return true; + }, geometry); } }; } // namespace resolve_variant +// TODO: This algorithm should use relate(pt, pt) strategy + + /*! \brief Closes or opens a geometry, according to its type \details Corrects a geometry w.r.t. closure points to all rings which do not diff --git a/include/boost/geometry/algorithms/detail/multi_modify.hpp b/include/boost/geometry/algorithms/detail/multi_modify.hpp index 9c2f18006..58597ed6f 100644 --- a/include/boost/geometry/algorithms/detail/multi_modify.hpp +++ b/include/boost/geometry/algorithms/detail/multi_modify.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2017-2020. -// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -32,27 +32,24 @@ namespace detail { -template +template struct multi_modify { + template static inline void apply(MultiGeometry& multi) { - typedef typename boost::range_iterator::type iterator_type; - for (iterator_type it = boost::begin(multi); - it != boost::end(multi); - ++it) + auto const end = boost::end(multi); + for (auto it = boost::begin(multi); it != end; ++it) { Policy::apply(*it); } } - template + template static inline void apply(MultiGeometry& multi, Strategy const& strategy) { - typedef typename boost::range_iterator::type iterator_type; - for (iterator_type it = boost::begin(multi); - it != boost::end(multi); - ++it) + auto const end = boost::end(multi); + for (auto it = boost::begin(multi); it != end; ++it) { Policy::apply(*it, strategy); } diff --git a/include/boost/geometry/algorithms/is_convex.hpp b/include/boost/geometry/algorithms/is_convex.hpp index 036b0d6b8..0d54111c9 100644 --- a/include/boost/geometry/algorithms/is_convex.hpp +++ b/include/boost/geometry/algorithms/is_convex.hpp @@ -17,12 +17,9 @@ #include -#include -#include -#include - #include #include +#include #include #include #include @@ -30,6 +27,8 @@ #include #include #include +#include +#include // For backward compatibility #include #include #include @@ -53,10 +52,7 @@ struct ring_is_convex static inline bool apply(Ring const& ring, Strategies const& strategies) { std::size_t n = boost::size(ring); - if (boost::size(ring) < core_detail::closure::minimum_ring_size - < - geometry::closure::value - >::value) + if (n < detail::minimum_ring_size::value) { // (Too) small rings are considered as non-concave, is convex return true; @@ -137,6 +133,17 @@ struct polygon_is_convex } }; +struct multi_polygon_is_convex +{ + template + static inline bool apply(MultiPolygon const& multi_polygon, Strategies const& strategies) + { + auto const size = boost::size(multi_polygon); + return size == 0 // For consistency with ring_is_convex + || (size == 1 && polygon_is_convex::apply(range::front(multi_polygon), strategies)); + } +}; + }} // namespace detail::is_convex #endif // DOXYGEN_NO_DETAIL @@ -151,14 +158,29 @@ template typename Geometry, typename Tag = typename tag::type > -struct is_convex : not_implemented -{}; +struct is_convex +{ + template + static inline bool apply(Geometry const&, Strategies const&) + { + // Convexity is not defined for PointLike and Linear geometries. + // We could implement this because the following definitions would work: + // - no line segment between two points on the interior or boundary ever goes outside. + // - convex_hull of geometry is equal to the original geometry, this implies equal + // topological dimension. + // For MultiPoint we'd have to check whether or not an arbitrary number of equal points + // is stored. + // MultiPolygon we'd have to check for continuous chain of Linestrings which would require + // the use of relate(pt, seg) or distance(pt, pt) strategy. + return false; + } +}; template struct is_convex { - template - static inline bool apply(Box const& , Strategy const& ) + template + static inline bool apply(Box const& , Strategies const& ) { // Any box is convex (TODO: consider spherical boxes) // TODO: in spherical and geographic the answer would be "false" most of the time. @@ -187,6 +209,10 @@ template struct is_convex : detail::is_convex::polygon_is_convex {}; +template +struct is_convex : detail::is_convex::multi_polygon_is_convex +{}; + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH @@ -238,9 +264,9 @@ struct is_convex } // namespace resolve_strategy -namespace resolve_variant { +namespace resolve_dynamic { -template +template ::type> struct is_convex { template @@ -251,38 +277,50 @@ struct is_convex } }; -template -struct is_convex > +template +struct is_convex { template - struct visitor: boost::static_visitor + static inline bool apply(Geometry const& geometry, Strategy const& strategy) { - Strategy const& m_strategy; - - visitor(Strategy const& strategy) : m_strategy(strategy) {} - - template - bool operator()(Geometry const& geometry) const + bool result = false; + traits::visit::apply([&](auto const& g) { - return is_convex::apply(geometry, m_strategy); - } - }; - - template - static inline bool apply(boost::variant const& geometry, - Strategy const& strategy) - { - return boost::apply_visitor(visitor(strategy), geometry); + result = is_convex>::apply(g, strategy); + }, geometry); + return result; } }; -} // namespace resolve_variant +// NOTE: This is a simple implementation checking if a GC contains single convex geometry. +// Technically a GC could store e.g. polygons touching with edges and together creating a convex +// region. To check this we'd require relate() strategy and the algorithm would be quite complex. +template +struct is_convex +{ + template + static inline bool apply(Geometry const& geometry, Strategy const& strategy) + { + bool result = false; + bool is_first = true; + detail::visit_breadth_first([&](auto const& g) + { + result = is_first + && is_convex>::apply(g, strategy); + is_first = false; + return result; + }, geometry); + return result; + } +}; + +} // namespace resolve_dynamic // TODO: documentation / qbk template inline bool is_convex(Geometry const& geometry) { - return resolve_variant::is_convex + return resolve_dynamic::is_convex < Geometry >::apply(geometry, geometry::default_strategy()); @@ -292,7 +330,7 @@ inline bool is_convex(Geometry const& geometry) template inline bool is_convex(Geometry const& geometry, Strategy const& strategy) { - return resolve_variant::is_convex::apply(geometry, strategy); + return resolve_dynamic::is_convex::apply(geometry, strategy); } diff --git a/include/boost/geometry/algorithms/reverse.hpp b/include/boost/geometry/algorithms/reverse.hpp index f124ee615..2fc4b1ccb 100644 --- a/include/boost/geometry/algorithms/reverse.hpp +++ b/include/boost/geometry/algorithms/reverse.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -24,15 +24,15 @@ #include #include -#include -#include -#include - #include #include +#include #include #include +#include +#include // For backward compatibility #include +#include namespace boost { namespace geometry @@ -61,11 +61,9 @@ struct polygon_reverse: private range_reverse { range_reverse::apply(exterior_ring(polygon)); - typename interior_return_type::type - rings = interior_rings(polygon); - - for (typename detail::interior_iterator::type - it = boost::begin(rings); it != boost::end(rings); ++it) + auto&& rings = interior_rings(polygon); + auto const end = boost::end(rings); + for (auto it = boost::begin(rings); it != end; ++it) { range_reverse::apply(*it); } @@ -110,21 +108,13 @@ struct reverse template struct reverse - : detail::multi_modify - < - Geometry, - detail::reverse::range_reverse - > + : detail::multi_modify {}; template struct reverse - : detail::multi_modify - < - Geometry, - detail::reverse::polygon_reverse - > + : detail::multi_modify {}; @@ -133,10 +123,10 @@ struct reverse #endif -namespace resolve_variant +namespace resolve_dynamic { -template +template ::type> struct reverse { static void apply(Geometry& geometry) @@ -146,25 +136,32 @@ struct reverse } }; -template -struct reverse > +template +struct reverse { - struct visitor: boost::static_visitor + static void apply(Geometry& geometry) { - template - void operator()(Geometry& geometry) const + traits::visit::apply([](auto & g) { - reverse::apply(geometry); - } - }; - - static inline void apply(boost::variant& geometry) - { - boost::apply_visitor(visitor(), geometry); + reverse>::apply(g); + }, geometry); } }; -} // namespace resolve_variant +template +struct reverse +{ + static void apply(Geometry& geometry) + { + detail::visit_breadth_first([](auto & g) + { + reverse>::apply(g); + return true; + }, geometry); + } +}; + +} // namespace resolve_dynamic /*! @@ -181,7 +178,7 @@ struct reverse > template inline void reverse(Geometry& geometry) { - resolve_variant::reverse::apply(geometry); + resolve_dynamic::reverse::apply(geometry); } }} // namespace boost::geometry diff --git a/include/boost/geometry/extensions/algorithms/remove_holes_if.hpp b/include/boost/geometry/extensions/algorithms/remove_holes_if.hpp index bdc6dcda2..529700721 100644 --- a/include/boost/geometry/extensions/algorithms/remove_holes_if.hpp +++ b/include/boost/geometry/extensions/algorithms/remove_holes_if.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -15,7 +19,7 @@ #include #include -#include +#include #include #include @@ -76,10 +80,8 @@ struct remove_holes_if template struct remove_holes_if - : detail::multi_modify_with_predicate + : detail::multi_modify < - MultiPolygon, - Predicate, detail::remove_holes_if::polygon_remove_holes_if < typename boost::range_value::type, Predicate diff --git a/test/algorithms/is_convex.cpp b/test/algorithms/is_convex.cpp index 6250bb9a4..7f0951e63 100644 --- a/test/algorithms/is_convex.cpp +++ b/test/algorithms/is_convex.cpp @@ -21,9 +21,10 @@ #include #include #include -#include -#include -#include +#include +#include + +#include template @@ -50,17 +51,38 @@ void test_all() std::string const rectangle_without_holes = "polygon((1 1, 1 4, 4 4, 4 1, 1 1))"; std::string const rectangle_with_holes = "polygon((1 1, 1 4, 4 4, 4 1, 1 1),(2 2, 3 2, 3 3, 2 3, 2 2))"; - test_one >("triangle", triangle, true); - test_one >("concave1", concave1, false); + using box_t = bg::model::box

; + using ring_t = bg::model::ring

; + using polygon_t = bg::model::polygon

; + using mpolygon_t = bg::model::multi_polygon; + using variant_t = boost::variant; + using collection_t = bg::model::geometry_collection; + + test_one("triangle", triangle, true); + test_one("concave1", concave1, false); test_one >("triangle", triangle, true); test_one >("concave1", concave1, false); - test_one >("triangle", triangle, true); - test_one >("concave1", concave1, false); - test_one >("rectangle_without_holes", rectangle_without_holes, true); - test_one >("rectangle_with_holes", rectangle_with_holes, false); + test_one("triangle", triangle, true); + test_one("concave1", concave1, false); + test_one("rectangle_without_holes", rectangle_without_holes, true); + test_one("rectangle_with_holes", rectangle_with_holes, false); - test_one >("box", "box(0 0,2 2)", true); + test_one("box", "box(0 0,2 2)", true); + + test_one("mpoly1", "multipolygon(((1 1, 1 4, 5 1, 1 1)))", true); + test_one("mpoly1", "multipolygon(((1 1, 1 4, 3 4, 3 3, 4 3, 4 4, 5 4, 5 1, 1 1)))", false); + test_one("mpoly2", "multipolygon(((1 1, 1 4, 5 1, 1 1)),((3 0, 3 1, 4 0, 3 0)))", false); + + test_one("variant1", triangle, true); + test_one("variant2", concave1, false); + + std::string const pref = "geometrycollection("; + std::string const post = ")"; + test_one("collection1", pref + triangle + post, true); + test_one("collection2", pref + concave1 + post, false); + test_one("collection3", pref + triangle + ", " + concave1 + post, false); + test_one("collection4", pref + triangle + ", polygon((3 0, 3 1, 4 0, 3 0))" + post, false); } diff --git a/test/algorithms/test_correct.hpp b/test/algorithms/test_correct.hpp index 1576b1602..9ea698c5e 100644 --- a/test/algorithms/test_correct.hpp +++ b/test/algorithms/test_correct.hpp @@ -5,6 +5,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -23,9 +27,10 @@ #include #include +#include +#include #include #include -#include template void check_geometry(Geometry const& geometry, std::string const& expected) @@ -41,13 +46,21 @@ void test_geometry(std::string const& wkt, std::string const& expected) { Geometry geometry; bg::read_wkt(wkt, geometry); - boost::variant v(geometry); bg::correct(geometry); check_geometry(geometry, expected); + boost::variant v(geometry); + bg::correct(v); check_geometry(v, expected); + + std::string const pref = "GEOMETRYCOLLECTION("; + std::string const post = ")"; + bg::model::geometry_collection> gc = { v }; + + bg::correct(gc); + check_geometry(gc, pref + expected + post); } From 6b49308808ab123fb22d2a0529b81861a8d9d909 Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Wed, 30 Jun 2021 12:51:28 +0300 Subject: [PATCH 08/74] Move side_by_triangle to strategy/cartesian --- .../agnostic/point_in_box_by_side.hpp | 6 +- .../strategies/cartesian/intersection.hpp | 2 +- .../cartesian/point_in_poly_winding.hpp | 2 +- .../strategies/cartesian/side_by_triangle.hpp | 270 +----------------- .../strategies/convex_hull/cartesian.hpp | 2 +- .../strategies/intersection_strategies.hpp | 4 +- .../strategies/is_convex/cartesian.hpp | 4 +- .../geometry/strategies/relate/cartesian.hpp | 3 +- .../boost/geometry/strategies/strategies.hpp | 3 +- .../strategy/cartesian/side_by_triangle.hpp | 262 +++++++++++++++++ .../strategy/cartesian/side_non_robust.hpp | 7 +- .../strategy/cartesian/side_robust.hpp | 23 +- .../geometry/util/select_most_precise.hpp | 40 +-- .../convex_hull/convex_hull_robust.cpp | 1 - .../convex_hull/test_convex_hull.hpp | 5 +- test/algorithms/overlay/relative_order.cpp | 4 +- test/strategies/spherical_side.cpp | 2 +- test/strategies/test_within.hpp | 3 +- 18 files changed, 317 insertions(+), 326 deletions(-) create mode 100644 include/boost/geometry/strategy/cartesian/side_by_triangle.hpp diff --git a/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp b/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp index c794a3b23..8c3f0ba0a 100644 --- a/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp +++ b/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp @@ -20,12 +20,16 @@ #include #include + #include #include + #include + +#include + #include #include -#include #include #include diff --git a/include/boost/geometry/strategies/cartesian/intersection.hpp b/include/boost/geometry/strategies/cartesian/intersection.hpp index cbf4aa486..f81a98998 100644 --- a/include/boost/geometry/strategies/cartesian/intersection.hpp +++ b/include/boost/geometry/strategies/cartesian/intersection.hpp @@ -38,13 +38,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include diff --git a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp index 3df4bcc44..3268d5a33 100644 --- a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp @@ -24,10 +24,10 @@ #include #include +#include #include #include -#include #include #include diff --git a/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp b/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp index 989f3fbb1..848570fd9 100644 --- a/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp +++ b/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp @@ -1,275 +1,21 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) +// Boost.Geometry -// 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) 2021, Oracle and/or its affiliates. -// This file was modified by Oracle on 2015-2021. -// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle -// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - -// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library -// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. - -// Use, modification and distribution is subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP -#include - -#include - -#include - -#include -#include -#include -#include - -#include - -#include +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") -namespace boost { namespace geometry -{ - -namespace strategy { namespace side -{ - -/*! -\brief Check at which side of a segment a point lies: - left of segment (> 0), right of segment (< 0), on segment (0) -\ingroup strategies -\tparam CalculationType \tparam_calculation - */ -template -class side_by_triangle -{ - template - struct eps_policy - { - eps_policy() {} - template - eps_policy(Type const& a, Type const& b, Type const& c, Type const& d) - : policy(a, b, c, d) - {} - Policy policy; - }; - - struct eps_empty - { - eps_empty() {} - template - eps_empty(Type const&, Type const&, Type const&, Type const&) {} - }; - -public : - typedef cartesian_tag cs_tag; - - // Template member function, because it is not always trivial - // or convenient to explicitly mention the typenames in the - // strategy-struct itself. - - // Types can be all three different. Therefore it is - // not implemented (anymore) as "segment" - - template - < - typename CoordinateType, - typename PromotedType, - typename P1, - typename P2, - typename P, - typename EpsPolicy - > - static inline - PromotedType side_value(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & eps_policy) - { - CoordinateType const x = get<0>(p); - CoordinateType const y = get<1>(p); - - CoordinateType const sx1 = get<0>(p1); - CoordinateType const sy1 = get<1>(p1); - CoordinateType const sx2 = get<0>(p2); - CoordinateType const sy2 = get<1>(p2); - - PromotedType const dx = sx2 - sx1; - PromotedType const dy = sy2 - sy1; - PromotedType const dpx = x - sx1; - PromotedType const dpy = y - sy1; - - eps_policy = EpsPolicy(dx, dy, dpx, dpy); - - return geometry::detail::determinant - ( - dx, dy, - dpx, dpy - ); - - } - - template - < - typename CoordinateType, - typename PromotedType, - typename P1, - typename P2, - typename P - > - static inline - PromotedType side_value(P1 const& p1, P2 const& p2, P const& p) - { - eps_empty dummy; - return side_value(p1, p2, p, dummy); - } - - - template - < - typename CoordinateType, - typename PromotedType, - bool AreAllIntegralCoordinates - > - struct compute_side_value - { - template - static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp) - { - return side_value(p1, p2, p, epsp); - } - }; - - template - struct compute_side_value - { - template - static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp) - { - // For robustness purposes, first check if any two points are - // the same; in this case simply return that the points are - // collinear - if (equals_point_point(p1, p2) - || equals_point_point(p1, p) - || equals_point_point(p2, p)) - { - return PromotedType(0); - } - - // The side_by_triangle strategy computes the signed area of - // the point triplet (p1, p2, p); as such it is (in theory) - // invariant under cyclic permutations of its three arguments. - // - // In the context of numerical errors that arise in - // floating-point computations, and in order to make the strategy - // consistent with respect to cyclic permutations of its three - // arguments, we cyclically permute them so that the first - // argument is always the lexicographically smallest point. - - typedef compare::cartesian less; - - if (less::apply(p, p1)) - { - if (less::apply(p, p2)) - { - // p is the lexicographically smallest - return side_value(p, p1, p2, epsp); - } - else - { - // p2 is the lexicographically smallest - return side_value(p2, p, p1, epsp); - } - } - - if (less::apply(p1, p2)) - { - // p1 is the lexicographically smallest - return side_value(p1, p2, p, epsp); - } - else - { - // p2 is the lexicographically smallest - return side_value(p2, p, p1, epsp); - } - } - }; - - - template - static inline int apply(P1 const& p1, P2 const& p2, P const& p) - { - typedef typename coordinate_type::type coordinate_type1; - typedef typename coordinate_type::type coordinate_type2; - typedef typename coordinate_type

::type coordinate_type3; - - typedef std::conditional_t - < - std::is_void::value, - typename select_most_precise - < - coordinate_type1, - coordinate_type2, - coordinate_type3 - >::type, - CalculationType - > coordinate_type; - - // Promote float->double, small int->int - typedef typename select_most_precise - < - coordinate_type, - double - >::type promoted_type; - - bool const are_all_integral_coordinates = - std::is_integral::value - && std::is_integral::value - && std::is_integral::value; - - eps_policy< math::detail::equals_factor_policy > epsp; - promoted_type s = compute_side_value - < - coordinate_type, promoted_type, are_all_integral_coordinates - >::apply(p1, p2, p, epsp); - - promoted_type const zero = promoted_type(); - return math::detail::equals_by_policy(s, zero, epsp.policy) ? 0 - : s > zero ? 1 - : -1; - } - -private: - template - static inline bool equals_point_point(P1 const& p1, P2 const& p2) - { - return strategy::within::cartesian_point_point::apply(p1, p2); - } -}; - - -#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS -namespace services -{ - -template -struct default_strategy -{ - typedef side_by_triangle type; -}; - -} -#endif - -}} // namespace strategy::side - -}} // namespace boost::geometry +#include #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP diff --git a/include/boost/geometry/strategies/convex_hull/cartesian.hpp b/include/boost/geometry/strategies/convex_hull/cartesian.hpp index 1bef4e389..c357ba95e 100644 --- a/include/boost/geometry/strategies/convex_hull/cartesian.hpp +++ b/include/boost/geometry/strategies/convex_hull/cartesian.hpp @@ -10,10 +10,10 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP #define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP +#include #include #include -#include namespace boost { namespace geometry { diff --git a/include/boost/geometry/strategies/intersection_strategies.hpp b/include/boost/geometry/strategies/intersection_strategies.hpp index bba6545c9..afb1afb5d 100644 --- a/include/boost/geometry/strategies/intersection_strategies.hpp +++ b/include/boost/geometry/strategies/intersection_strategies.hpp @@ -19,12 +19,12 @@ #include #include +#include + #include #include #include - #include -#include #include #include diff --git a/include/boost/geometry/strategies/is_convex/cartesian.hpp b/include/boost/geometry/strategies/is_convex/cartesian.hpp index 4297c223b..d274086ab 100644 --- a/include/boost/geometry/strategies/is_convex/cartesian.hpp +++ b/include/boost/geometry/strategies/is_convex/cartesian.hpp @@ -10,12 +10,14 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_IS_CONVEX_CARTESIAN_HPP #define BOOST_GEOMETRY_STRATEGIES_IS_CONVEX_CARTESIAN_HPP +#include +#include #include -#include #include #include #include + #include diff --git a/include/boost/geometry/strategies/relate/cartesian.hpp b/include/boost/geometry/strategies/relate/cartesian.hpp index 5b418913d..913ef714a 100644 --- a/include/boost/geometry/strategies/relate/cartesian.hpp +++ b/include/boost/geometry/strategies/relate/cartesian.hpp @@ -20,13 +20,14 @@ #include #include #include -#include #include #include #include #include +#include +#include #include diff --git a/include/boost/geometry/strategies/strategies.hpp b/include/boost/geometry/strategies/strategies.hpp index 66cbc9383..541ae1d25 100644 --- a/include/boost/geometry/strategies/strategies.hpp +++ b/include/boost/geometry/strategies/strategies.hpp @@ -67,7 +67,6 @@ #include #include #include -#include #include #include @@ -135,6 +134,8 @@ #include #include #include +#include +#include #include #include diff --git a/include/boost/geometry/strategy/cartesian/side_by_triangle.hpp b/include/boost/geometry/strategy/cartesian/side_by_triangle.hpp new file mode 100644 index 000000000..56436a2a2 --- /dev/null +++ b/include/boost/geometry/strategy/cartesian/side_by_triangle.hpp @@ -0,0 +1,262 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// 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. + +// This file was modified by Oracle on 2015-2021. +// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library +// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_BY_TRIANGLE_HPP +#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_BY_TRIANGLE_HPP + + +#include + +#include + +#include + +#include +#include +#include +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace side +{ + +/*! +\brief Check at which side of a segment a point lies: + left of segment (> 0), right of segment (< 0), on segment (0) +\ingroup strategies +\tparam CalculationType \tparam_calculation + */ +template +class side_by_triangle +{ + template + struct eps_policy + { + eps_policy() {} + template + eps_policy(Type const& a, Type const& b, Type const& c, Type const& d) + : policy(a, b, c, d) + {} + Policy policy; + }; + + struct eps_empty + { + eps_empty() {} + template + eps_empty(Type const&, Type const&, Type const&, Type const&) {} + }; + +public : + typedef cartesian_tag cs_tag; + + // Template member function, because it is not always trivial + // or convenient to explicitly mention the typenames in the + // strategy-struct itself. + + // Types can be all three different. Therefore it is + // not implemented (anymore) as "segment" + + template + < + typename CoordinateType, + typename PromotedType, + typename P1, + typename P2, + typename P, + typename EpsPolicy + > + static inline + PromotedType side_value(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & eps_policy) + { + CoordinateType const x = get<0>(p); + CoordinateType const y = get<1>(p); + + CoordinateType const sx1 = get<0>(p1); + CoordinateType const sy1 = get<1>(p1); + CoordinateType const sx2 = get<0>(p2); + CoordinateType const sy2 = get<1>(p2); + + PromotedType const dx = sx2 - sx1; + PromotedType const dy = sy2 - sy1; + PromotedType const dpx = x - sx1; + PromotedType const dpy = y - sy1; + + eps_policy = EpsPolicy(dx, dy, dpx, dpy); + + return geometry::detail::determinant + ( + dx, dy, + dpx, dpy + ); + + } + + template + < + typename CoordinateType, + typename PromotedType, + typename P1, + typename P2, + typename P + > + static inline + PromotedType side_value(P1 const& p1, P2 const& p2, P const& p) + { + eps_empty dummy; + return side_value(p1, p2, p, dummy); + } + + + template + < + typename CoordinateType, + typename PromotedType, + bool AreAllIntegralCoordinates + > + struct compute_side_value + { + template + static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp) + { + return side_value(p1, p2, p, epsp); + } + }; + + template + struct compute_side_value + { + template + static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp) + { + // For robustness purposes, first check if any two points are + // the same; in this case simply return that the points are + // collinear + if (equals_point_point(p1, p2) + || equals_point_point(p1, p) + || equals_point_point(p2, p)) + { + return PromotedType(0); + } + + // The side_by_triangle strategy computes the signed area of + // the point triplet (p1, p2, p); as such it is (in theory) + // invariant under cyclic permutations of its three arguments. + // + // In the context of numerical errors that arise in + // floating-point computations, and in order to make the strategy + // consistent with respect to cyclic permutations of its three + // arguments, we cyclically permute them so that the first + // argument is always the lexicographically smallest point. + + typedef compare::cartesian less; + + if (less::apply(p, p1)) + { + if (less::apply(p, p2)) + { + // p is the lexicographically smallest + return side_value(p, p1, p2, epsp); + } + else + { + // p2 is the lexicographically smallest + return side_value(p2, p, p1, epsp); + } + } + + if (less::apply(p1, p2)) + { + // p1 is the lexicographically smallest + return side_value(p1, p2, p, epsp); + } + else + { + // p2 is the lexicographically smallest + return side_value(p2, p, p1, epsp); + } + } + }; + + + template + static inline int apply(P1 const& p1, P2 const& p2, P const& p) + { + typedef typename coordinate_type::type coordinate_type1; + typedef typename coordinate_type::type coordinate_type2; + typedef typename coordinate_type

::type coordinate_type3; + + typedef std::conditional_t + < + std::is_void::value, + typename select_most_precise + < + coordinate_type1, + coordinate_type2, + coordinate_type3 + >::type, + CalculationType + > coordinate_type; + + // Promote float->double, small int->int + typedef typename select_most_precise + < + coordinate_type, + double + >::type promoted_type; + + bool const are_all_integral_coordinates = + std::is_integral::value + && std::is_integral::value + && std::is_integral::value; + + eps_policy< math::detail::equals_factor_policy > epsp; + promoted_type s = compute_side_value + < + coordinate_type, promoted_type, are_all_integral_coordinates + >::apply(p1, p2, p, epsp); + + promoted_type const zero = promoted_type(); + return math::detail::equals_by_policy(s, zero, epsp.policy) ? 0 + : s > zero ? 1 + : -1; + } + +private: + template + static inline bool equals_point_point(P1 const& p1, P2 const& p2) + { + return strategy::within::cartesian_point_point::apply(p1, p2); + } +}; + +}} // namespace strategy::side + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_BY_TRIANGLE_HPP diff --git a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp index 098cb9bd4..add8e7972 100644 --- a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2020, Oracle and/or its affiliates. +// Copyright (c) 2020-2021, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle @@ -21,7 +21,7 @@ namespace strategy { namespace side { /*! -\brief Adaptive precision predicate to check at which side of a segment a point lies: +\brief Predicate to check at which side of a segment a point lies: left of segment (>0), right of segment (< 0), on segment (0). \ingroup strategies \tparam CalculationType \tparam_calculation @@ -35,8 +35,6 @@ struct side_non_robust { public: //! \brief Computes double the signed area of the CCW triangle p1, p2, p - -#ifndef DOXYGEN_SHOULD_SKIP_THIS template < typename P1, @@ -66,7 +64,6 @@ public: return detleft > detright ? 1 : (detleft < detright ? -1 : 0 ); } -#endif }; diff --git a/include/boost/geometry/strategy/cartesian/side_robust.hpp b/include/boost/geometry/strategy/cartesian/side_robust.hpp index 9e69a0c80..61fd6827c 100644 --- a/include/boost/geometry/strategy/cartesian/side_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_robust.hpp @@ -17,12 +17,10 @@ #ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP #define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP -#include - -#include - #include +#include + #include #include #include @@ -133,7 +131,7 @@ public: #ifndef DOXYGEN_SHOULD_SKIP_THIS template - < + < typename P1, typename P2, typename P @@ -171,6 +169,21 @@ public: }; +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef side_robust type; +}; + +} + +#endif + }} // namespace strategy::side }} // namespace boost::geometry diff --git a/include/boost/geometry/util/select_most_precise.hpp b/include/boost/geometry/util/select_most_precise.hpp index 3fb8d8a73..d6c6337b4 100644 --- a/include/boost/geometry/util/select_most_precise.hpp +++ b/include/boost/geometry/util/select_most_precise.hpp @@ -30,6 +30,7 @@ namespace boost { namespace geometry namespace detail { namespace select_most_precise { + // 0 - void // 1 - integral // 2 - floating point @@ -54,43 +55,6 @@ struct type_priority > {}; -/* -// 0 - void -// 1 - integral (int, long int) -// 2 - floating point (float, double) -// 3 - long long int -// 4 - long double -// 5 - non-fundamental -template -struct type_priority - : std::conditional_t - < - std::is_void::value, - std::integral_constant, - std::conditional_t - < - std::is_fundamental::value, - std::conditional_t - < - std::is_same::value, - std::integral_constant, - std::conditional_t - < - std::is_same::value, - std::integral_constant, - std::conditional_t - < - std::is_floating_point::value, - std::integral_constant, - std::integral_constant - > - > - >, - std::integral_constant - > - > -{}; -*/ template struct type_size @@ -155,7 +119,7 @@ struct select_most_precise T2, std::conditional_t // priority1 == priority2 < - (priority1 == 0 || priority1 == 5), // both void or non-fundamental + (priority1 == 0 || priority1 == 3), // both void or non-fundamental T1, std::conditional_t // both fundamental < diff --git a/test/algorithms/convex_hull/convex_hull_robust.cpp b/test/algorithms/convex_hull/convex_hull_robust.cpp index 1a53321fd..9ee6e55f4 100644 --- a/test/algorithms/convex_hull/convex_hull_robust.cpp +++ b/test/algorithms/convex_hull/convex_hull_robust.cpp @@ -82,7 +82,6 @@ void test_all() polygon_wkt3, 5, 4, 1.4210854715202004e-14); test_geometry, non_robust_cartesian_sbt >( polygon_wkt3, 5, 5, 1.69333333333333265e-13); - return ; // missing one point could lead in arbitrary large errors in area auto polygon_wkt4 = "polygon((0.10000000000000001 0.10000000000000001,\ diff --git a/test/algorithms/convex_hull/test_convex_hull.hpp b/test/algorithms/convex_hull/test_convex_hull.hpp index c901e3c0b..d1b01bd38 100644 --- a/test/algorithms/convex_hull/test_convex_hull.hpp +++ b/test/algorithms/convex_hull/test_convex_hull.hpp @@ -31,9 +31,10 @@ #include #include -#include -#include #include +#include +#include +#include #include diff --git a/test/algorithms/overlay/relative_order.cpp b/test/algorithms/overlay/relative_order.cpp index 8d2a5b47a..9a7cda29e 100644 --- a/test/algorithms/overlay/relative_order.cpp +++ b/test/algorithms/overlay/relative_order.cpp @@ -31,9 +31,9 @@ # include #endif -#include -#include +#include +#include template void test_with_point(std::string const& /*caseid*/, diff --git a/test/strategies/spherical_side.cpp b/test/strategies/spherical_side.cpp index 2e426fa74..51345dd21 100644 --- a/test/strategies/spherical_side.cpp +++ b/test/strategies/spherical_side.cpp @@ -27,7 +27,7 @@ #include //#include #include -#include +#include #include #include diff --git a/test/strategies/test_within.hpp b/test/strategies/test_within.hpp index f4280beb0..57ffdefa1 100644 --- a/test/strategies/test_within.hpp +++ b/test/strategies/test_within.hpp @@ -21,6 +21,8 @@ #include #include +#include + #include #include #include @@ -28,7 +30,6 @@ #include #include -#include #include // TEMP From e3eb4bae2cbac767ca1ff106dcbce504fcd0771c Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Fri, 2 Jul 2021 16:35:32 +0300 Subject: [PATCH 09/74] Simplify the use of eps_policy in orient2d --- include/boost/geometry/util/precise_math.hpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/include/boost/geometry/util/precise_math.hpp b/include/boost/geometry/util/precise_math.hpp index eccf08800..e14c20fbb 100644 --- a/include/boost/geometry/util/precise_math.hpp +++ b/include/boost/geometry/util/precise_math.hpp @@ -368,28 +368,14 @@ inline RealNumber orient2d(vec2d const& p1, vec2d const& p3, EpsPolicy& eps_policy) { - auto const x = p3.x; - auto const y = p3.y; - - auto const sx1 = p1.x; - auto const sy1 = p1.y; - auto const sx2 = p2.x; - auto const sy2 = p2.y; - - - auto const dx = sx2 - sx1; - auto const dy = sy2 - sy1; - auto const dpx = x - sx1; - auto const dpy = y - sy1; - - eps_policy = EpsPolicy(dx, dy, dpx, dpy); - std::array t1, t2, t3, t4; t1[0] = p1.x - p3.x; t2[0] = p2.y - p3.y; t3[0] = p1.y - p3.y; t4[0] = p2.x - p3.x; + eps_policy = EpsPolicy(t1[0], t2[0], t3[0], t4[0]); + std::array t5_01, t6_01; t5_01[0] = t1[0] * t2[0]; t6_01[0] = t3[0] * t4[0]; From c1f8ab10de002891c34561ff3e756f996171df04 Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Fri, 2 Jul 2021 18:03:05 +0300 Subject: [PATCH 10/74] Refactoring the policies in side_robust --- .../strategy/cartesian/side_robust.hpp | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/include/boost/geometry/strategy/cartesian/side_robust.hpp b/include/boost/geometry/strategy/cartesian/side_robust.hpp index 61fd6827c..9d4ba785d 100644 --- a/include/boost/geometry/strategy/cartesian/side_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_robust.hpp @@ -32,12 +32,11 @@ namespace boost { namespace geometry namespace strategy { namespace side { -struct eps_equals_policy +struct epsilon_equals_policy { public: - template - static auto apply(T1 a, T2 b, Policy policy) + static bool apply(T1 const& a, T2 const& b, Policy const& policy) { return boost::geometry::math::detail::equals_by_policy(a, b, policy); } @@ -47,7 +46,7 @@ struct fp_equals_policy { public: template - static auto apply(T1 a, T2 b, Policy) + static bool apply(T1 const& a, T2 const& b, Policy const&) { return a == b; } @@ -65,20 +64,32 @@ public: template < typename CalculationType = void, - typename EpsPolicy = eps_equals_policy, + typename EqualsPolicy = epsilon_equals_policy, std::size_t Robustness = 3 > struct side_robust { - template - struct eps_policy + + template + struct epsilon_policy { - eps_policy() {} + using Policy = boost::geometry::math::detail::equals_factor_policy; + + epsilon_policy() {} + template - eps_policy(Type const& a, Type const& b, Type const& c, Type const& d) - : policy(a, b, c, d) + epsilon_policy(Type const& a, Type const& b, Type const& c, Type const& d) + : m_policy(a, b, c, d) {} - Policy policy; + Policy m_policy; + + public: + + template + bool apply(T1 a, T2 b) const + { + return EqualsPolicy::apply(a, b, m_policy); + } }; public: @@ -152,15 +163,11 @@ public: double >::type; - eps_policy - < - boost::geometry::math::detail::equals_factor_policy - > epsp; - + epsilon_policy epsp; promoted_type sv = side_value(p1, p2, p, epsp); - promoted_type const zero = promoted_type(); - return EpsPolicy::apply(sv, zero, epsp.policy) ? 0 + + return epsp.apply(sv, zero) ? 0 : sv > zero ? 1 : -1; } From 6ca6dadede270d22a746b120a70b30cbbf02e4e2 Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Tue, 13 Jul 2021 13:58:01 +0300 Subject: [PATCH 11/74] Rewrite non robust side predicate --- .../strategy/cartesian/side_non_robust.hpp | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp index add8e7972..9400f9bd6 100644 --- a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp @@ -14,6 +14,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -49,20 +51,43 @@ public: P1, P2, P - >::type coordinate_type; + >::type CoordinateType; typedef typename select_most_precise < - coordinate_type, + CoordinateType, double - >::type promoted_type; + >::type PromotedType; - auto detleft = (promoted_type(get<0>(p1)) - promoted_type(get<0>(p))) - * (promoted_type(get<1>(p2)) - promoted_type(get<1>(p))); - auto detright = (promoted_type(get<1>(p1)) - promoted_type(get<1>(p))) - * (promoted_type(get<0>(p2)) - promoted_type(get<0>(p))); + CoordinateType const x = get<0>(p); + CoordinateType const y = get<1>(p); - return detleft > detright ? 1 : (detleft < detright ? -1 : 0 ); + CoordinateType const sx1 = get<0>(p1); + CoordinateType const sy1 = get<1>(p1); + CoordinateType const sx2 = get<0>(p2); + CoordinateType const sy2 = get<1>(p2); + //non-robust 1 + //the following is 2x slower in some generic cases when compiled with g++ + //(tested versions 9 and 10) + // + //auto detleft = (sx1 - x) * (sy2 - y); + //auto detright = (sy1 - y) * (sx2 - x); + //return detleft > detright ? 1 : (detleft < detright ? -1 : 0 ); + + //non-robust 2 + PromotedType const dx = sx2 - sx1; + PromotedType const dy = sy2 - sy1; + PromotedType const dpx = x - sx1; + PromotedType const dpy = y - sy1; + + PromotedType sv = geometry::detail::determinant + ( + dx, dy, + dpx, dpy + ); + PromotedType const zero = PromotedType(); + + return sv == 0 ? 0 : sv > zero ? 1 : -1; } }; From 08f7e66f79f168c61ef552382fb12ac4d1dbda4d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 1 Jul 2021 22:26:05 +0200 Subject: [PATCH 12/74] [test] Drop library dependencies in tests. If possible drop type_traits, mpl, typeof, foreach, assign. Rearrange some includes. --- test/algorithms/area/area.cpp | 4 +- test/algorithms/area/area_sph_geo.cpp | 7 +- test/algorithms/buffer/buffer_linestring.cpp | 12 +- .../buffer/buffer_linestring_aimes.cpp | 6 +- .../buffer/buffer_multi_linestring.cpp | 6 +- .../buffer/buffer_multi_polygon.cpp | 6 +- test/algorithms/buffer/buffer_polygon.cpp | 12 +- test/algorithms/buffer/test_buffer.hpp | 17 +- test/algorithms/buffer/test_buffer_svg.hpp | 30 +- .../buffer/test_buffer_svg_per_turn.hpp | 7 +- test/algorithms/centroid.cpp | 7 +- test/algorithms/check_validity.hpp | 8 +- test/algorithms/comparable_distance.cpp | 65 ++- .../covered_by/covered_by_sph_geo.cpp | 8 +- .../detail/calculate_point_order.cpp | 5 +- test/algorithms/detail/partition.cpp | 51 +-- .../detail/sections/range_by_section.cpp | 4 +- .../detail/sections/sectionalize.cpp | 6 +- test/algorithms/detail/tupled_output.cpp | 7 +- test/algorithms/distance/distance.cpp | 25 +- .../distance/distance_brute_force.hpp | 27 +- .../distance/distance_geo_linear_box.cpp | 11 +- .../distance/distance_se_geo_ar_ar.cpp | 7 +- .../distance/distance_se_geo_l_ar.cpp | 9 +- .../distance/distance_se_geo_l_l.cpp | 9 +- .../distance/distance_se_geo_pl_ar.cpp | 9 +- .../distance/test_distance_common.hpp | 33 +- .../distance/test_distance_geo_common.hpp | 43 +- .../distance/test_distance_se_common.hpp | 37 +- .../envelope_expand/envelope_on_spheroid.cpp | 70 ++-- .../envelope_expand/expand_on_spheroid.cpp | 42 +- .../envelope_expand/test_envelope.hpp | 33 +- .../test_envelope_expand_on_spheroid.hpp | 7 +- test/algorithms/equals/equals.cpp | 13 +- test/algorithms/overlay/assemble.cpp | 24 +- test/algorithms/overlay/dissolver.cpp | 14 +- test/algorithms/overlay/get_turn_info.cpp | 17 +- test/algorithms/overlay/get_turns.cpp | 6 +- .../overlay/get_turns_linear_linear.cpp | 13 +- .../overlay/get_turns_linear_linear_sph.cpp | 8 +- test/algorithms/overlay/overlay.cpp | 15 +- test/algorithms/overlay/relative_order.cpp | 12 +- test/algorithms/overlay/select_rings.cpp | 43 +- .../overlay/self_intersection_points.cpp | 8 +- test/algorithms/overlay/sort_by_side.cpp | 68 ++- .../algorithms/overlay/sort_by_side_basic.cpp | 41 +- test/algorithms/overlay/split_rings.cpp | 6 +- test/algorithms/overlay/traverse.cpp | 65 ++- test/algorithms/overlay/traverse_ccw.cpp | 20 +- test/algorithms/point_on_surface.cpp | 9 +- test/algorithms/relate/nan_cases.hpp | 6 +- test/algorithms/relate/relate_areal_areal.cpp | 13 +- .../relate/relate_linear_areal_sph.cpp | 6 +- .../relate/relate_linear_linear.cpp | 29 +- .../relate/relate_linear_linear_sph.cpp | 27 +- test/algorithms/relate/test_relate.hpp | 15 +- .../set_operations/difference/difference.cpp | 6 +- .../difference/difference_areal_linear.cpp | 7 +- .../difference/difference_tupled.cpp | 50 +-- .../difference/test_difference.hpp | 1 - .../intersection/intersection.cpp | 8 +- .../intersection/test_intersection.hpp | 12 +- .../test_intersection_linear_linear.hpp | 18 +- .../test_set_ops_linear_linear.hpp | 91 +--- .../set_operations/test_set_ops_pointlike.hpp | 33 +- .../set_operations/union/test_union.hpp | 21 +- .../algorithms/set_operations/union/union.cpp | 6 +- test/algorithms/simplify_countries.cpp | 21 +- test/algorithms/transform.cpp | 9 +- .../within/within_pointlike_geometry.cpp | 30 +- test/core/point_type.cpp | 5 +- test/core/tag.cpp | 9 +- test/geometry_test_common.hpp | 9 +- test/iterators/flatten_iterator.cpp | 44 +- test/iterators/point_iterator.cpp | 75 ++-- test/iterators/segment_iterator.cpp | 391 +++++++++--------- test/policies/rescale_policy.cpp | 28 +- .../general_intersection_precision.cpp | 6 +- .../overlay/areal_areal/test_overlay_p_q.hpp | 13 +- .../overlay/areal_areal/ticket_9081.cpp | 88 ++-- .../overlay/buffer/multi_point_growth.cpp | 22 +- .../buffer/recursive_polygons_buffer.cpp | 10 +- .../recursive_polygons_linear_areal.cpp | 39 +- test/srs/proj4.hpp | 51 +-- test/srs/projection_interface_s.cpp | 4 +- test/srs/spar.cpp | 52 ++- test/strategies/distance.cpp | 8 +- test/strategies/distance_default_result.cpp | 33 +- test/strategies/douglas_peucker.cpp | 50 ++- test/strategies/pythagoras.cpp | 62 +-- test/strategies/pythagoras_point_box.cpp | 85 ++-- test/strategies/vincenty.cpp | 13 +- test/string_from_type.hpp | 10 +- test/test_common/test_point.hpp | 7 +- test/test_common/with_pointer.hpp | 7 +- test/test_geometries/custom_lon_lat_point.hpp | 10 +- test/to_svg.hpp | 17 +- test/util/calculation_type.cpp | 18 +- test/util/is_implemented.cpp | 4 +- test/util/math_sqrt.cpp | 123 +++--- test/util/promote_integral.cpp | 25 +- test/util/select_most_precise.cpp | 8 +- 102 files changed, 1255 insertions(+), 1492 deletions(-) diff --git a/test/algorithms/area/area.cpp b/test/algorithms/area/area.cpp index 7f6f28d88..ee107465e 100644 --- a/test/algorithms/area/area.cpp +++ b/test/algorithms/area/area.cpp @@ -73,13 +73,13 @@ void test_all() ("POLYGON((1 0,0 1,-1 0,0 -1,1 0))", 2); typedef typename bg::coordinate_type

::type coord_type; - if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (BOOST_GEOMETRY_CONDITION((std::is_same::value))) { test_geometry > ("POLYGON((100000001 100000000, 100000000 100000001, \ 99999999 100000000, 100000000 99999999))", 2); } - else if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + else if (BOOST_GEOMETRY_CONDITION((std::is_same::value))) { test_geometry > ("POLYGON((100001 100000, 100000 100001, \ diff --git a/test/algorithms/area/area_sph_geo.cpp b/test/algorithms/area/area_sph_geo.cpp index cda94d165..c9b47bfe1 100644 --- a/test/algorithms/area/area_sph_geo.cpp +++ b/test/algorithms/area/area_sph_geo.cpp @@ -6,9 +6,8 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2015, 2016, 2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. - +// This file was modified by Oracle on 2015-2021. +// Modifications copyright (c) 2015-2021, 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 @@ -430,7 +429,7 @@ void test_spherical_geo() /*if (polar) { // Create colatitudes (measured from pole) - BOOST_FOREACH(pt& p, aurha) + for (pt& p : aurha) { bg::set<1>(p, ct(90) - bg::get<1>(p)); } diff --git a/test/algorithms/buffer/buffer_linestring.cpp b/test/algorithms/buffer/buffer_linestring.cpp index 1c3f9dab4..b892ec30d 100644 --- a/test/algorithms/buffer/buffer_linestring.cpp +++ b/test/algorithms/buffer/buffer_linestring.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2012-2019 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016. -// Modifications copyright (c) 2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2021. +// Modifications copyright (c) 2016-2021, 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, @@ -128,7 +128,7 @@ void test_all() ut_settings const settings; ut_settings const specific_settings - = BOOST_GEOMETRY_CONDITION((boost::is_same::value)) + = BOOST_GEOMETRY_CONDITION((std::is_same::value)) ? ut_settings(0.02) : settings; // Simplex (join-type is not relevant) @@ -258,7 +258,7 @@ void test_all() test_one("mysql_report_2015_04_01", mysql_report_2015_04_01, join_round(32), end_round(32), 632.234, d100); } - if (! BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (! BOOST_GEOMETRY_CONDITION((std::is_same::value))) { ut_settings settings; settings.tolerance = 0.1; @@ -313,7 +313,7 @@ void test_all() 27862.733459829971, 5.9518403867035365); - if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (BOOST_GEOMETRY_CONDITION((std::is_same::value))) { test_one("mysql_report_2015_09_08a", mysql_report_2015_09_08a, join_round32, end_round32, 0.0, 1.0); test_one("mysql_report_2015_09_08b", mysql_report_2015_09_08b, join_round32, end_round32, 0.0, 1099511627778.0); @@ -390,7 +390,7 @@ template void test_invalid() { typedef typename bg::coordinate_type

::type coor_type; - if (! BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (! BOOST_GEOMETRY_CONDITION((std::is_same::value))) { return; } diff --git a/test/algorithms/buffer/buffer_linestring_aimes.cpp b/test/algorithms/buffer/buffer_linestring_aimes.cpp index d82708bb0..86279e0e1 100644 --- a/test/algorithms/buffer/buffer_linestring_aimes.cpp +++ b/test/algorithms/buffer/buffer_linestring_aimes.cpp @@ -3,6 +3,10 @@ // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -425,7 +429,7 @@ void test_aimes() typedef bg::model::polygon

polygon; typedef typename bg::coordinate_type

::type coor_type; - if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (BOOST_GEOMETRY_CONDITION((std::is_same::value))) { std::cout << "This unit test can't be tested with float," << " the coordinate values are too small." << std::endl; diff --git a/test/algorithms/buffer/buffer_multi_linestring.cpp b/test/algorithms/buffer/buffer_multi_linestring.cpp index 0c454111a..4b06877aa 100644 --- a/test/algorithms/buffer/buffer_multi_linestring.cpp +++ b/test/algorithms/buffer/buffer_multi_linestring.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2012-2019 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016. -// Modifications copyright (c) 2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2021. +// Modifications copyright (c) 2016-2021, 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, @@ -141,7 +141,7 @@ void test_all() test_one("mikado4_small", mikado4, join_round32, end_flat, 1930.785, 10.0); } - if (! BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (! BOOST_GEOMETRY_CONDITION((std::is_same::value))) { // Coordinates in one linestring vary so much that // length = geometry::math::sqrt(dx * dx + dy * dy); returns a value of inf for length diff --git a/test/algorithms/buffer/buffer_multi_polygon.cpp b/test/algorithms/buffer/buffer_multi_polygon.cpp index edd78d591..03ab006ae 100644 --- a/test/algorithms/buffer/buffer_multi_polygon.cpp +++ b/test/algorithms/buffer/buffer_multi_polygon.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2012-2019 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016. -// Modifications copyright (c) 2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2021. +// Modifications copyright (c) 2016-2021, 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, @@ -657,7 +657,7 @@ void test_all() join_round32, end_round32, 0.0, -10.0); // Check cases with extreme coordinates on assertions - if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (BOOST_GEOMETRY_CONDITION((std::is_same::value))) { test_one("mysql_report_2015_07_05_1", mysql_report_2015_07_05_1, diff --git a/test/algorithms/buffer/buffer_polygon.cpp b/test/algorithms/buffer/buffer_polygon.cpp index 6c1b70e7a..d1cd8e96a 100644 --- a/test/algorithms/buffer/buffer_polygon.cpp +++ b/test/algorithms/buffer/buffer_polygon.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2012-2019 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016, 2019. -// Modifications copyright (c) 2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2021. +// Modifications copyright (c) 2016-2021, 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, @@ -535,7 +535,7 @@ void test_all() test_one("italy_part2_5", italy_part2, join_round, end_flat, {12496082120, 12496082124}, 5 * 1000.0); - if (! BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (! BOOST_GEOMETRY_CONDITION((std::is_same::value))) { ut_settings settings; settings.set_test_validity(false); @@ -571,7 +571,7 @@ void test_all() test_one("ticket_10398_1_25", ticket_10398_1, join_miter, end_flat, 246.7329, -2.5); } - if (! BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (! BOOST_GEOMETRY_CONDITION((std::is_same::value))) { // Test issue 369 as reported (1.15e-3) and some variants // Use high tolerance because output areas are very small @@ -590,7 +590,7 @@ void test_all() test_one("issue_369_1000", issue_369, jr, er, 7.881e-10, distance / 1000.0, specific); } - if (! BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (! BOOST_GEOMETRY_CONDITION((std::is_same::value))) { // Test issue 555 as reported (-0.000001) and some variants bg::strategy::buffer::join_round jr(180); @@ -639,7 +639,7 @@ void test_all() mysql_report_2015_02_17_3, join_round32, end_round32, 64.0, -1.0); - if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (BOOST_GEOMETRY_CONDITION((std::is_same::value))) { // These extreme testcases, containing huge coordinate differences // and huge buffer distances, are to verify assertions. diff --git a/test/algorithms/buffer/test_buffer.hpp b/test/algorithms/buffer/test_buffer.hpp index 8a3d92d12..3691e6127 100644 --- a/test/algorithms/buffer/test_buffer.hpp +++ b/test/algorithms/buffer/test_buffer.hpp @@ -24,7 +24,6 @@ #include #include -#include #include #include @@ -161,12 +160,12 @@ void test_buffer(std::string const& caseid, typedef typename bg::tag::type tag; // TODO use something different here: - std::string type = boost::is_same::value ? "poly" - : boost::is_same::value ? "line" - : boost::is_same::value ? "point" - : boost::is_same::value ? "multipoly" - : boost::is_same::value ? "multiline" - : boost::is_same::value ? "multipoint" + std::string type = std::is_same::value ? "poly" + : std::is_same::value ? "line" + : std::is_same::value ? "point" + : std::is_same::value ? "multipoly" + : std::is_same::value ? "multiline" + : std::is_same::value ? "multipoint" : "" ; @@ -184,8 +183,8 @@ void test_buffer(std::string const& caseid, std::string end_name = EndTestProperties::name(); if ( BOOST_GEOMETRY_CONDITION(( - boost::is_same::value - || boost::is_same::value )) ) + std::is_same::value + || std::is_same::value )) ) { join_name.clear(); } diff --git a/test/algorithms/buffer/test_buffer_svg.hpp b/test/algorithms/buffer/test_buffer_svg.hpp index 9d0fb9f85..f8df1b13f 100644 --- a/test/algorithms/buffer/test_buffer_svg.hpp +++ b/test/algorithms/buffer/test_buffer_svg.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 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, @@ -28,8 +28,8 @@ # endif #endif -#include #include +#include #include @@ -116,8 +116,7 @@ private : std::map > offsets; - for (typename boost::range_iterator::type it = - boost::begin(turns); it != boost::end(turns); ++it) + for (auto it = boost::begin(turns); it != boost::end(turns); ++it) { if (m_zoom && bg::disjoint(it->point, m_alternate_box)) { @@ -192,9 +191,7 @@ private : typedef typename boost::range_value::type ring_type; typedef typename bg::point_type::type point_type; - for(typename boost::range_iterator::type it = boost::begin(pieces); - it != boost::end(pieces); - ++it) + for (auto it = boost::begin(pieces); it != boost::end(pieces); ++it) { const piece_type& piece = *it; bg::segment_identifier seg_id = piece.first_seg_id; @@ -274,8 +271,7 @@ private : template inline void map_traversed_rings(TraversedRings const& traversed_rings) { - for(typename boost::range_iterator::type it - = boost::begin(traversed_rings); it != boost::end(traversed_rings); ++it) + for (auto it = boost::begin(traversed_rings); it != boost::end(traversed_rings); ++it) { m_mapper.map(*it, "opacity:0.4;fill:none;stroke:rgb(0,255,0);stroke-width:2"); } @@ -284,8 +280,7 @@ private : template inline void map_offsetted_rings(OffsettedRings const& offsetted_rings) { - for(typename boost::range_iterator::type it - = boost::begin(offsetted_rings); it != boost::end(offsetted_rings); ++it) + for (auto it = boost::begin(offsetted_rings); it != boost::end(offsetted_rings); ++it) { if (it->discarded()) { @@ -349,14 +344,7 @@ public : void map_input_output(Mapper& mapper, Geometry const& geometry, GeometryBuffer const& buffered, bool negative) { - bool const areal = boost::is_same - < - typename bg::tag_cast - < - typename bg::tag::type, - bg::areal_tag - >::type, bg::areal_tag - >::type::value; + bool const areal = bg::util::is_areal::value; if (m_zoom) { @@ -385,7 +373,7 @@ public : bg::detail::overlay::assign_null_policy >(geometry, strategy, rescale_policy, turns, policy); - BOOST_FOREACH(turn_info const& turn, turns) + for (turn_info const& turn : turns) { mapper.map(turn.point, "fill:rgb(255,128,0);stroke:rgb(0,0,100);stroke-width:1", 3); } diff --git a/test/algorithms/buffer/test_buffer_svg_per_turn.hpp b/test/algorithms/buffer/test_buffer_svg_per_turn.hpp index e48d333d1..be01f4b95 100644 --- a/test/algorithms/buffer/test_buffer_svg_per_turn.hpp +++ b/test/algorithms/buffer/test_buffer_svg_per_turn.hpp @@ -2,6 +2,11 @@ // Unit Test Helper // Copyright (c) 2010-2019 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -132,7 +137,7 @@ public : return; } - BOOST_FOREACH(pair_type const& p, points) + for (pair_type const& p : points) { mappers.push_back(new mapper_visitor(complete_caseid, p.second, p.first)); } diff --git a/test/algorithms/centroid.cpp b/test/algorithms/centroid.cpp index 248ebc72b..e418cedce 100644 --- a/test/algorithms/centroid.cpp +++ b/test/algorithms/centroid.cpp @@ -5,9 +5,8 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014, 2015. -// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates. - +// This file was modified by Oracle on 2014-2021. +// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -91,7 +90,7 @@ void test_2d() coord_type m = (std::numeric_limits::max)(); bg::append(ls, P(coord_type(m), coord_type(-m))); bg::append(ls, P(coord_type(0.0001), coord_type(0.000))); - if (BOOST_GEOMETRY_CONDITION((boost::is_same::type, double>::value))) + if (BOOST_GEOMETRY_CONDITION((std::is_same::type, double>::value))) { // for doubles the INF is detected and the calculation stopped // currently for Geometries for which the centroid can't be calculated diff --git a/test/algorithms/check_validity.hpp b/test/algorithms/check_validity.hpp index 388ca6fad..c02ff3f01 100644 --- a/test/algorithms/check_validity.hpp +++ b/test/algorithms/check_validity.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2017 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -9,8 +13,6 @@ #ifndef BOOST_GEOMETRY_TEST_CHECK_VALIDITY_HPP #define BOOST_GEOMETRY_TEST_CHECK_VALIDITY_HPP -#include - #include template @@ -64,7 +66,7 @@ struct check_validity std::string& message) { typedef typename boost::range_value::type single_type; - BOOST_FOREACH(single_type const& element, geometry) + for (single_type const& element : geometry) { if (! is_output_valid(element, case_id, g1, g2, message)) { diff --git a/test/algorithms/comparable_distance.cpp b/test/algorithms/comparable_distance.cpp index bb96dc205..1df2e6a45 100644 --- a/test/algorithms/comparable_distance.cpp +++ b/test/algorithms/comparable_distance.cpp @@ -6,9 +6,8 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2017. -// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. - +// This file was modified by Oracle on 2014-2021. +// Modifications 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 @@ -22,9 +21,6 @@ #include -#include -#include -#include #include #include @@ -188,8 +184,8 @@ struct test_variant_different_default_strategy variant_type v1, v2; - BOOST_MPL_ASSERT(( - boost::is_same + BOOST_GEOMETRY_STATIC_ASSERT( + (std::is_same < typename bg::comparable_distance_result < @@ -199,8 +195,8 @@ struct test_variant_different_default_strategy < point_type, point_type, bg::default_strategy >::type - > - )); + >::value), + "Unexpected result type"); // Default strategy v1 = point; @@ -261,27 +257,27 @@ struct test_variant_same_default_strategy variant_type v1, v2; - BOOST_MPL_ASSERT(( - boost::is_same + BOOST_GEOMETRY_STATIC_ASSERT( + (std::is_same < typename bg::comparable_distance_result < variant_type, variant_type, bg::default_strategy >::type, ExpectedResultType - > - )); + >::value), + "Unexpected result type"); - BOOST_MPL_ASSERT(( - boost::is_same + BOOST_GEOMETRY_STATIC_ASSERT( + (std::is_same < typename bg::comparable_distance_result < point_type, point_type, bg::default_strategy >::type, ExpectedResultType - > - )); + >::value), + "Unexpected result type"); // Default strategy v1 = point; @@ -352,27 +348,27 @@ struct test_variant_with_strategy strategy_type strategy; - BOOST_MPL_ASSERT(( - boost::is_same + BOOST_GEOMETRY_STATIC_ASSERT( + (std::is_same < typename bg::comparable_distance_result < variant_type, variant_type, strategy_type >::type, ExpectedResultType - > - )); + >::value), + "Unexpected result type"); - BOOST_MPL_ASSERT(( - boost::is_same + BOOST_GEOMETRY_STATIC_ASSERT( + (std::is_same < typename bg::comparable_distance_result < segment_type, linestring_type, strategy_type >::type, ExpectedResultType - > - )); + >::value), + "Unexpected result type"); // Passed strategy v1 = seg; @@ -422,7 +418,7 @@ struct test_variant_with_strategy } }; -template ::value> +template ::value> struct check_result { template @@ -459,23 +455,24 @@ struct test_variant_boxes variant_type v1 = box1, v2 = box2; - typedef typename boost::mpl::if_c + typedef typename std::conditional < - boost::is_float::value, + std::is_floating_point::value, double, typename bg::util::detail::default_integral::type >::type expected_result_type; - BOOST_MPL_ASSERT(( - boost::is_same + BOOST_GEOMETRY_STATIC_ASSERT( + (std::is_same < typename bg::comparable_distance_result < variant_type, variant_type, bg::default_strategy >::type, expected_result_type - > - )); + >::value), + "Unexpected result type" + ); // Default strategy check_result::apply(bg::comparable_distance(v1, v2), @@ -491,7 +488,7 @@ struct test_variant_boxes int test_main(int, char* []) { test_double_result_from_integer(); - test_double_result_from_integer(); + test_double_result_from_integer(); test_all >(); test_all >(); diff --git a/test/algorithms/covered_by/covered_by_sph_geo.cpp b/test/algorithms/covered_by/covered_by_sph_geo.cpp index 665b2802f..94730d52c 100644 --- a/test/algorithms/covered_by/covered_by_sph_geo.cpp +++ b/test/algorithms/covered_by/covered_by_sph_geo.cpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016 Oracle and/or its affiliates. +// Copyright (c) 2016-2021 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, @@ -82,12 +82,12 @@ void test_box_box() template void test_point_polygon() { - typename boost::mpl::if_ + std::conditional_t < - boost::is_same::type, bg::geographic_tag>, + std::is_same::type, bg::geographic_tag>::value, bg::strategy::within::geographic_winding

, bg::strategy::within::spherical_winding

- >::type s; + > s; typedef bg::model::polygon

poly; diff --git a/test/algorithms/detail/calculate_point_order.cpp b/test/algorithms/detail/calculate_point_order.cpp index 401136313..38922155f 100644 --- a/test/algorithms/detail/calculate_point_order.cpp +++ b/test/algorithms/detail/calculate_point_order.cpp @@ -1,8 +1,7 @@ // Boost.Geometry // Unit Test -// Copyright (c) 2019, Oracle and/or its affiliates. - +// Copyright (c) 2019-2021, 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. @@ -89,7 +88,7 @@ inline void test_one(std::string const& ring_wkt, bg::order_selector expected) std::rotate(boost::begin(ring), boost::begin(ring) + 1, boost::end(ring)); // it seems that area method doesn't work for invalid "opened" polygons - //if (! boost::is_same::value) + //if (! std::is_same::value) { P p = bg::range::front(ring); bg::range::push_back(ring, p); diff --git a/test/algorithms/detail/partition.cpp b/test/algorithms/detail/partition.cpp index 9d63668d8..c1549f729 100644 --- a/test/algorithms/detail/partition.cpp +++ b/test/algorithms/detail/partition.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021 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, @@ -15,19 +15,20 @@ #include +#include +#include +#include +#include +#include -#include #include #include #include -#include - -#include - #if defined(TEST_WITH_SVG) # include #endif +#include #include #include @@ -151,7 +152,7 @@ void test_boxes(std::string const& wkt_box_list, double expected_area, int expec std::vector boxes; int index = 1; - BOOST_FOREACH(std::string const& wkt, wkt_boxes) + for (std::string const& wkt : wkt_boxes) { boxes.push_back(sample(index++, wkt)); } @@ -229,10 +230,10 @@ void test_points(std::string const& wkt1, std::string const& wkt2, int expected_ bg::read_wkt(wkt2, mp2); int id = 1; - BOOST_FOREACH(point_item& p, mp1) + for (point_item& p : mp1) { p.id = id++; } id = 1; - BOOST_FOREACH(point_item& p, mp2) + for (point_item& p : mp2) { p.id = id++; } point_visitor visitor; @@ -352,9 +353,9 @@ void test_many_points(int seed, int size, int count) // Test equality in quadratic loop int expected_count = 0; - BOOST_FOREACH(point_item const& item1, mp1) + for (point_item const& item1 : mp1) { - BOOST_FOREACH(point_item const& item2, mp2) + for (point_item const& item2 : mp2) { if (bg::equals(item1, item2)) { @@ -395,11 +396,11 @@ void test_many_points(int seed, int size, int count) BOOST_CHECK_EQUAL(visitor.count, expected_count); #if defined(TEST_WITH_SVG) - BOOST_FOREACH(point_item const& item, mp1) + for (point_item const& item : mp1) { mapper.map(item, "fill:rgb(255,128,0);stroke:rgb(0,0,100);stroke-width:1", 8); } - BOOST_FOREACH(point_item const& item, mp2) + for (point_item const& item : mp2) { mapper.map(item, "fill:rgb(0,128,255);stroke:rgb(0,0,100);stroke-width:1", 4); } @@ -447,9 +448,9 @@ void test_many_boxes(int seed, int size, int count) // Test equality in quadratic loop int expected_count = 0; double expected_area = 0.0; - BOOST_FOREACH(box_item const& item1, boxes) + for (box_item const& item1 : boxes) { - BOOST_FOREACH(box_item const& item2, boxes) + for (box_item const& item2 : boxes) { if (item1.id < item2.id) { @@ -478,7 +479,7 @@ void test_many_boxes(int seed, int size, int count) p.x = size + 1; p.y = size + 1; mapper.add(p); } - BOOST_FOREACH(box_item const& item, boxes) + for (box_item const& item : boxes) { mapper.map(item.box, "opacity:0.6;fill:rgb(50,50,210);stroke:rgb(0,0,0);stroke-width:1"); } @@ -515,9 +516,9 @@ void test_two_collections(int seed1, int seed2, int size, int count) // Get expectations in quadratic loop int expected_count = 0; double expected_area = 0.0; - BOOST_FOREACH(box_item const& item1, boxes1) + for (box_item const& item1 : boxes1) { - BOOST_FOREACH(box_item const& item2, boxes2) + for (box_item const& item2 : boxes2) { if (bg::intersects(item1.box, item2.box)) { @@ -543,11 +544,11 @@ void test_two_collections(int seed1, int seed2, int size, int count) p.x = size + 1; p.y = size + 1; mapper.add(p); } - BOOST_FOREACH(box_item const& item, boxes1) + for (box_item const& item : boxes1) { mapper.map(item.box, "opacity:0.6;fill:rgb(50,50,210);stroke:rgb(0,0,0);stroke-width:1"); } - BOOST_FOREACH(box_item const& item, boxes2) + for (box_item const& item : boxes2) { mapper.map(item.box, "opacity:0.6;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:1"); } @@ -584,9 +585,9 @@ void test_heterogenuous_collections(int seed1, int seed2, int size, int count) // Get expectations in quadratic loop int expected_count = 0; - BOOST_FOREACH(point_item const& point, points) + for (point_item const& point : points) { - BOOST_FOREACH(box_item const& box_item, boxes) + for (box_item const& box_item : boxes) { if (bg::within(point, box_item.box)) { @@ -609,11 +610,11 @@ void test_heterogenuous_collections(int seed1, int seed2, int size, int count) p.x = size + 1; p.y = size + 1; mapper.add(p); } - BOOST_FOREACH(point_item const& point, points) + for (point_item const& point : points) { mapper.map(point, "fill:rgb(255,128,0);stroke:rgb(0,0,100);stroke-width:1", 8); } - BOOST_FOREACH(box_item const& item, boxes) + for (box_item const& item : boxes) { mapper.map(item.box, "opacity:0.6;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:1"); } diff --git a/test/algorithms/detail/sections/range_by_section.cpp b/test/algorithms/detail/sections/range_by_section.cpp index 1069c4905..b963a759d 100644 --- a/test/algorithms/detail/sections/range_by_section.cpp +++ b/test/algorithms/detail/sections/range_by_section.cpp @@ -11,7 +11,7 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include + #include #define BOOST_GEOMETRY_UNIT_TEST_SECTIONALIZE @@ -58,7 +58,7 @@ void test_sectionalize(std::string const /*caseid*/, Geometry const& geometry, s view_type const >::type range_iterator; - BOOST_FOREACH(typename sections::value_type const& sec, s) + for (typename sections::value_type const& sec : s) { cview_type cview(bg::range_by_section(geometry, sec)); view_type view(cview); diff --git a/test/algorithms/detail/sections/sectionalize.cpp b/test/algorithms/detail/sections/sectionalize.cpp index ce448a1fd..6493c2561 100644 --- a/test/algorithms/detail/sections/sectionalize.cpp +++ b/test/algorithms/detail/sections/sectionalize.cpp @@ -5,8 +5,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020, Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -102,7 +102,7 @@ void test_sectionalize(std::string const& caseid, G const& g, std::size_t sectio // Check if sections are consecutive and consistent int previous_index = -1; - BOOST_FOREACH(typename sections::value_type const& sec, s) + for (typename sections::value_type const& sec : s) { if (sec.begin_index > 0) { diff --git a/test/algorithms/detail/tupled_output.cpp b/test/algorithms/detail/tupled_output.cpp index 3454f307b..8b9265a2b 100644 --- a/test/algorithms/detail/tupled_output.cpp +++ b/test/algorithms/detail/tupled_output.cpp @@ -1,8 +1,7 @@ // Boost.Geometry // Unit Test -// Copyright (c) 2019 Oracle and/or its affiliates. - +// Copyright (c) 2019-2021 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, @@ -34,14 +33,14 @@ template void test_range_values() { typedef typename bgd::tupled_range_values::type tuple_s; - BOOST_CHECK_EQUAL((boost::is_same::value), true); + BOOST_CHECK_EQUAL((std::is_same::value), true); } template void test_back_inserters() { typedef typename bgd::tupled_back_inserters::type tuple_bi; - BOOST_CHECK_EQUAL((boost::is_same::value), true); + BOOST_CHECK_EQUAL((std::is_same::value), true); TupleM tup; bgd::tupled_back_inserters::apply(tup); diff --git a/test/algorithms/distance/distance.cpp b/test/algorithms/distance/distance.cpp index 30e8eb63f..dbf66afe0 100644 --- a/test/algorithms/distance/distance.cpp +++ b/test/algorithms/distance/distance.cpp @@ -5,6 +5,9 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// Copyright (c) 2021 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -20,8 +23,6 @@ #include "test_distance.hpp" #include -#include -#include #include #include @@ -81,7 +82,9 @@ void test_distance_point() BOOST_CONCEPT_ASSERT( (bg::concepts::PointDistanceStrategy) ); typedef typename services::return_type::type cab_return_type; - BOOST_MPL_ASSERT((boost::is_same::type>)); + BOOST_GEOMETRY_STATIC_ASSERT( + (std::is_same::type>::value), + "Unexpected result type"); taxicab_distance tcd; cab_return_type d = bg::distance(p1, p2, tcd); @@ -412,8 +415,8 @@ void test_large_integers() bg::read_wkt(a, da); bg::read_wkt(b, db); - BOOST_AUTO(idist, bg::distance(ia, ib)); - BOOST_AUTO(ddist, bg::distance(da, db)); + auto const idist = bg::distance(ia, ib); + auto const ddist = bg::distance(da, db); BOOST_CHECK_MESSAGE(std::abs(idist - ddist) < 0.1, "within different from within"); @@ -431,8 +434,8 @@ void test_large_integers() bg::read_wkt(a, da); bg::read_wkt(b, db); - BOOST_AUTO(idist, bg::distance(ia, ib)); - BOOST_AUTO(ddist, bg::distance(da, db)); + auto const idist = bg::distance(ia, ib); + auto const ddist = bg::distance(da, db); BOOST_CHECK_MESSAGE(std::abs(idist - ddist) < 0.1, "within different from within"); @@ -457,16 +460,16 @@ void test_variant() variant_type v1, v2; - BOOST_MPL_ASSERT(( - boost::is_same + BOOST_GEOMETRY_STATIC_ASSERT( + (std::is_same < typename bg::distance_result < variant_type, variant_type, bg::default_strategy >::type, double - > - )); + >::value), + "Unexpected result type"); // Default strategy v1 = point; diff --git a/test/algorithms/distance/distance_brute_force.hpp b/test/algorithms/distance/distance_brute_force.hpp index 1e5b8b998..64ad16cd6 100644 --- a/test/algorithms/distance/distance_brute_force.hpp +++ b/test/algorithms/distance/distance_brute_force.hpp @@ -1,8 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2014-2020 Oracle and/or its affiliates. - +// Copyright (c) 2014-2021 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -15,8 +14,6 @@ #include -#include -#include #include #include #include @@ -46,17 +43,13 @@ struct distance_from_bg { template struct use_distance_from_bg - { - typedef typename boost::mpl::or_ + : util::bool_constant < - boost::is_same::type, point_tag>, - typename boost::mpl::or_ - < - boost::is_same::type, segment_tag>, - boost::is_same::type, box_tag> - >::type - >::type type; - }; + std::is_same::type, point_tag>::value + || std::is_same::type, segment_tag>::value + || std::is_same::type, box_tag>::value + > + {}; template static inline @@ -65,8 +58,10 @@ struct distance_from_bg Geometry2 const& geometry2, Strategy const& strategy) { - BOOST_MPL_ASSERT((typename use_distance_from_bg::type)); - BOOST_MPL_ASSERT((typename use_distance_from_bg::type)); + BOOST_GEOMETRY_STATIC_ASSERT((use_distance_from_bg::value), + "Unexpected kind of Geometry1"); + BOOST_GEOMETRY_STATIC_ASSERT((use_distance_from_bg::value), + "Unexpected kind of Geometry1"); return geometry::distance(geometry1, geometry2, strategy); } diff --git a/test/algorithms/distance/distance_geo_linear_box.cpp b/test/algorithms/distance/distance_geo_linear_box.cpp index b7287201d..bb9abac29 100644 --- a/test/algorithms/distance/distance_geo_linear_box.cpp +++ b/test/algorithms/distance/distance_geo_linear_box.cpp @@ -1,25 +1,24 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2017-2020 Oracle and/or its affiliates. - +// Copyright (c) 2017-2021 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html +#ifdef BOOST_GEOMETRY_TEST_DEBUG #include +#endif + +#include #ifndef BOOST_TEST_MODULE #define BOOST_TEST_MODULE test_distance_geographic_linear_areal #endif -#include - #include -#include -#include #include "test_distance_geo_common.hpp" //#include "test_empty_geometry.hpp" diff --git a/test/algorithms/distance/distance_se_geo_ar_ar.cpp b/test/algorithms/distance/distance_se_geo_ar_ar.cpp index 449ea50b0..a0b809af9 100644 --- a/test/algorithms/distance/distance_se_geo_ar_ar.cpp +++ b/test/algorithms/distance/distance_se_geo_ar_ar.cpp @@ -1,8 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2017-2020 Oracle and/or its affiliates. - +// Copyright (c) 2017-2021 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 @@ -13,11 +12,7 @@ #define BOOST_TEST_MODULE test_distance_geographic_areal_areal #endif -#include - #include -#include -#include #include "test_distance_geo_common.hpp" #include "test_empty_geometry.hpp" diff --git a/test/algorithms/distance/distance_se_geo_l_ar.cpp b/test/algorithms/distance/distance_se_geo_l_ar.cpp index dca46a264..ae26ce6b7 100644 --- a/test/algorithms/distance/distance_se_geo_l_ar.cpp +++ b/test/algorithms/distance/distance_se_geo_l_ar.cpp @@ -1,25 +1,22 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2017-2020 Oracle and/or its affiliates. - +// Copyright (c) 2017-2021 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html +#ifdef BOOST_GEOMETRY_TEST_DEBUG #include +#endif #ifndef BOOST_TEST_MODULE #define BOOST_TEST_MODULE test_distance_geographic_linear_areal #endif -#include - #include -#include -#include #include "test_distance_geo_common.hpp" #include "test_empty_geometry.hpp" diff --git a/test/algorithms/distance/distance_se_geo_l_l.cpp b/test/algorithms/distance/distance_se_geo_l_l.cpp index 7f0119f59..75d3b9b5e 100644 --- a/test/algorithms/distance/distance_se_geo_l_l.cpp +++ b/test/algorithms/distance/distance_se_geo_l_l.cpp @@ -1,25 +1,22 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2018-2020 Oracle and/or its affiliates. - +// Copyright (c) 2018-2021 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html +#ifdef BOOST_GEOMETRY_TEST_DEBUG #include +#endif #ifndef BOOST_TEST_MODULE #define BOOST_TEST_MODULE test_distance_geographic_linear_linear #endif -#include - #include -#include -#include #include "test_distance_geo_common.hpp" #include "test_empty_geometry.hpp" diff --git a/test/algorithms/distance/distance_se_geo_pl_ar.cpp b/test/algorithms/distance/distance_se_geo_pl_ar.cpp index bd8fce71b..67ca9fadd 100644 --- a/test/algorithms/distance/distance_se_geo_pl_ar.cpp +++ b/test/algorithms/distance/distance_se_geo_pl_ar.cpp @@ -1,25 +1,22 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2017-2020, Oracle and/or its affiliates. - +// Copyright (c) 2017-2021 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html +#ifdef BOOST_GEOMETRY_TEST_DEBUG #include +#endif #ifndef BOOST_TEST_MODULE #define BOOST_TEST_MODULE test_distance_geographic_pointlike_areal #endif -#include - #include -#include -#include #include "test_distance_geo_common.hpp" #include "test_empty_geometry.hpp" diff --git a/test/algorithms/distance/test_distance_common.hpp b/test/algorithms/distance/test_distance_common.hpp index fb8002f99..88c2747d5 100644 --- a/test/algorithms/distance/test_distance_common.hpp +++ b/test/algorithms/distance/test_distance_common.hpp @@ -1,8 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2014-2017, Oracle and/or its affiliates. - +// 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 @@ -16,28 +15,16 @@ #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 @@ -207,11 +194,11 @@ private: Strategy, G1, G2 >::type distance_result_from_strategy; - static const bool same_regular = boost::is_same + static const bool same_regular = std::is_same < default_distance_result, distance_result_from_strategy - >::type::value; + >::value; BOOST_CHECK( same_regular ); @@ -231,11 +218,11 @@ private: G2 >::type comparable_distance_result_from_strategy; - static const bool same_comparable = boost::is_same + static const bool same_comparable = std::is_same < default_comparable_distance_result, comparable_distance_result_from_strategy - >::type::value; + >::value; BOOST_CHECK( same_comparable ); diff --git a/test/algorithms/distance/test_distance_geo_common.hpp b/test/algorithms/distance/test_distance_geo_common.hpp index 7620c883a..58695c16c 100644 --- a/test/algorithms/distance/test_distance_geo_common.hpp +++ b/test/algorithms/distance/test_distance_geo_common.hpp @@ -1,9 +1,9 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2016-2017, Oracle and/or its affiliates. - +// Copyright (c) 2016-2021, 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -14,29 +14,18 @@ #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 @@ -229,7 +218,7 @@ template struct dispatch }; // Specialization for segments -template <> struct dispatch +template <> struct dispatch { template static inline Segment swap(Segment const& s) @@ -259,7 +248,7 @@ template <> struct dispatch }; // Specialization for boxes -template <> struct dispatch +template <> struct dispatch { template static inline T swap(T const& t) @@ -283,7 +272,7 @@ template <> struct dispatch // Specialization for points -template <> struct dispatch +template <> struct dispatch { template static inline T swap(T const& t) @@ -412,11 +401,11 @@ struct test_distance_of_geometries Strategy, Geometry1, Geometry2 >::type distance_result_from_strategy; - static const bool same_regular = boost::is_same + static const bool same_regular = std::is_same < default_distance_result, distance_result_from_strategy - >::type::value; + >::value; BOOST_CHECK(same_regular); @@ -482,12 +471,12 @@ struct test_distance_of_geometries { Geometry1 g1 = dispatch < - typename boost::geometry::tag::type + typename bg::tag::type >::swap(geometry1); Geometry2 g2 = dispatch < - typename boost::geometry::tag::type + typename bg::tag::type >::swap(geometry2); // check distance with given strategy @@ -510,12 +499,12 @@ struct test_distance_of_geometries { Geometry1 g1 = dispatch < - typename boost::geometry::tag::type + typename bg::tag::type >::mirror(geometry1); Geometry2 g2 = dispatch < - typename boost::geometry::tag::type + typename bg::tag::type >::mirror(geometry2); // check distance with given strategy diff --git a/test/algorithms/distance/test_distance_se_common.hpp b/test/algorithms/distance/test_distance_se_common.hpp index 1909c27f9..e8febcd75 100644 --- a/test/algorithms/distance/test_distance_se_common.hpp +++ b/test/algorithms/distance/test_distance_se_common.hpp @@ -1,8 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2014-2017, Oracle and/or its affiliates. - +// 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 @@ -12,31 +11,21 @@ #ifndef BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP #define BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP +#ifdef BOOST_GEOMETRY_TEST_DEBUG #include +#endif + #include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - #include #include #include +#include + +#include +#include + #include #include @@ -192,11 +181,11 @@ struct test_distance_of_geometries Strategy, Geometry1, Geometry2 >::type distance_result_from_strategy; - static const bool same_regular = boost::is_same + static const bool same_regular = std::is_same < default_distance_result, distance_result_from_strategy - >::type::value; + >::value; BOOST_CHECK(same_regular); @@ -212,11 +201,11 @@ struct test_distance_of_geometries Geometry2 >::type comparable_distance_result_from_strategy; - static const bool same_comparable = boost::is_same + static const bool same_comparable = std::is_same < default_comparable_distance_result, comparable_distance_result_from_strategy - >::type::value; + >::value; BOOST_CHECK( same_comparable ); diff --git a/test/algorithms/envelope_expand/envelope_on_spheroid.cpp b/test/algorithms/envelope_expand/envelope_on_spheroid.cpp index 047955ecd..d09e7ddc3 100644 --- a/test/algorithms/envelope_expand/envelope_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/envelope_on_spheroid.cpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2015-2020, Oracle and/or its affiliates. +// Copyright (c) 2015-2021, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -22,34 +22,24 @@ #include #include -#include -#include - #include -#include -#include -#include -#include - -#include - -#include - -#include -#include +#include +#include +#include "test_envelope_expand_on_spheroid.hpp" #include #include #include - +#include +#include +#include +#include #include - -#include "test_envelope_expand_on_spheroid.hpp" - -//TEMP -#include -#include +#include +#include +#include +#include template @@ -74,22 +64,22 @@ struct test_envelope typedef bg::strategy::envelope::spherical_box box_strategy_t; typedef bg::strategy::envelope::geographic, double> strategy_t; - typename boost::mpl::if_c + std::conditional_t < - boost::is_same::type, bg::point_tag>::value, + std::is_same::type, bg::point_tag>::value, point_strategy_t, - typename boost::mpl::if_c + std::conditional_t < - boost::is_same::type, bg::multi_point_tag>::value, + std::is_same::type, bg::multi_point_tag>::value, multi_point_strategy_t, - typename boost::mpl::if_c + std::conditional_t < - boost::is_same::type, bg::box_tag>::value, + std::is_same::type, bg::box_tag>::value, box_strategy_t, strategy_t - >::type - >::type - >::type strategy; + > + > + > strategy; bg::envelope(geometry, detected, strategy); } @@ -327,26 +317,16 @@ public: // test the reverse of a geometry if it is either linear or ring -template ::type> +template struct test_reverse_geometry { - static bool const is_linear = - boost::is_same::value - || boost::is_same::value - || boost::is_same::value; + static bool const is_linear = bg::util::is_linear::value; // currently disable rings static bool const is_ring = false; - // static bool const is_ring = boost::is_same::value; + // static bool const is_ring = bg::util::is_ring::value; - typedef typename boost::mpl::if_c - < - is_linear || is_ring, - boost::true_type, - boost::false_type - >::type type; - - static bool const value = type::value; + static bool const value = (is_linear || is_ring); }; template diff --git a/test/algorithms/envelope_expand/expand_on_spheroid.cpp b/test/algorithms/envelope_expand/expand_on_spheroid.cpp index 16c3a24bd..50e0fc387 100644 --- a/test/algorithms/envelope_expand/expand_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/expand_on_spheroid.cpp @@ -1,8 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2015-2020, Oracle and/or its affiliates. - +// Copyright (c) 2015-2021, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -17,41 +16,32 @@ #include #include - #include #include #include #include -#include - -#include -#include -#include - -#include - -#include - -#include - -#include -#include - #include #include #include #include #include -#include "test_envelope_expand_on_spheroid.hpp" +#include +#include +#include -// TEMP -#include -#include -#include -#include +#include + +#include +#include + +#include + +#include + +#include "test_envelope_expand_on_spheroid.hpp" class test_expand_on_spheroid @@ -353,7 +343,7 @@ public: basic_tester < - boost::is_same + std::is_same < typename bg::tag::type, bg::box_tag @@ -1070,7 +1060,7 @@ void test_expand_make_inverse() typedef bg::model::segment segment_type; typedef test_expand_on_spheroid tester; - box_type box = boost::geometry::make_inverse(); + box_type box = bg::make_inverse(); tester::apply("bi01", box, diff --git a/test/algorithms/envelope_expand/test_envelope.hpp b/test/algorithms/envelope_expand/test_envelope.hpp index c0dc91639..64792366c 100644 --- a/test/algorithms/envelope_expand/test_envelope.hpp +++ b/test/algorithms/envelope_expand/test_envelope.hpp @@ -2,6 +2,11 @@ // Unit Test // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -28,13 +33,13 @@ struct check_result template struct check_result { - typedef typename bg::coordinate_type::type ctype; - typedef typename boost::mpl::if_ - < - boost::is_arithmetic, - double, - ctype - >::type type; + using ctype = typename bg::coordinate_type::type; + using type = std::conditional_t + < + (std::is_integral::value || std::is_floating_point::value), + double, + ctype + >; static void apply(Box const& b, const type& x1, const type& y1, const type& /*z1*/, const type& x2, const type& y2, const type& /*z2*/) @@ -50,13 +55,13 @@ struct check_result template struct check_result { - typedef typename bg::coordinate_type::type ctype; - typedef typename boost::mpl::if_ - < - boost::is_arithmetic, - double, - ctype - >::type type; + using ctype = typename bg::coordinate_type::type; + using type = std::conditional_t + < + (std::is_integral::value || std::is_floating_point::value), + double, + ctype + >; static void apply(Box const& b, const type& x1, const type& y1, const type& z1, const type& x2, const type& y2, const type& z2) diff --git a/test/algorithms/envelope_expand/test_envelope_expand_on_spheroid.hpp b/test/algorithms/envelope_expand/test_envelope_expand_on_spheroid.hpp index cd6c0e2a8..caf5402f4 100644 --- a/test/algorithms/envelope_expand/test_envelope_expand_on_spheroid.hpp +++ b/test/algorithms/envelope_expand/test_envelope_expand_on_spheroid.hpp @@ -1,8 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2015-2017, Oracle and/or its affiliates. - +// Copyright (c) 2015-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 @@ -18,8 +17,6 @@ #include #include -#include - #include #include #include @@ -66,7 +63,7 @@ struct rng template char const* units2string() { - if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (BOOST_GEOMETRY_CONDITION((std::is_same::value))) { return "degrees"; } diff --git a/test/algorithms/equals/equals.cpp b/test/algorithms/equals/equals.cpp index 8e0d23848..dd347709d 100644 --- a/test/algorithms/equals/equals.cpp +++ b/test/algorithms/equals/equals.cpp @@ -3,9 +3,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2020. -// Modifications copyright (c) 2013-2020 Oracle and/or its affiliates. - +// This file was modified by Oracle on 2013-2021. +// Modifications copyright (c) 2013-2021 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, @@ -14,8 +13,6 @@ #include "test_equals.hpp" -#include - #include #include @@ -59,7 +56,8 @@ void test_segment_segment() template void test_linestring_linestring() { - typedef bgm::linestring

ls; + using coord_t = typename bg::coordinate_type

::type; + using ls = bgm::linestring

; test_geometry("ls2d_1", "LINESTRING(1 1, 3 3)", "LINESTRING(3 3, 1 1)", true); test_geometry("ls2d_2", "LINESTRING(1 1, 3 3, 2 5)", "LINESTRING(1 1, 2 2, 3 3, 2 5)", true); @@ -82,8 +80,7 @@ void test_linestring_linestring() test_geometry("ls2d_overl_ring2", "LINESTRING(0 0,5 0,5 5,0 5,0 0)", "LINESTRING(5 5,5 0,0 0,0 5,5 5,5 0)", true); // https://svn.boost.org/trac/boost/ticket/10904 - if ( BOOST_GEOMETRY_CONDITION( - boost::is_floating_point::type>::value ) ) + if ( BOOST_GEOMETRY_CONDITION(std::is_floating_point::value) ) { test_geometry("ls2d_small1", "LINESTRING(5.6956521739130430148634331999347 -0.60869565217391330413931882503675,5.5 -0.50000000000000066613381477509392)", diff --git a/test/algorithms/overlay/assemble.cpp b/test/algorithms/overlay/assemble.cpp index 78965692a..d53bd9d4a 100644 --- a/test/algorithms/overlay/assemble.cpp +++ b/test/algorithms/overlay/assemble.cpp @@ -3,9 +3,8 @@ // Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2019. -// Modifications copyright (c) 2019, Oracle and/or its affiliates. - +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021, 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,24 +18,22 @@ #include -#include - #include #include #include #include #include #include -#include #include #include -#include - #include #include +#include + +#include #if defined(TEST_WITH_SVG) @@ -60,19 +57,19 @@ inline void test_assemble(std::string const& id, Geometry const& p, Geometry con type area_i = 0, area_u = 0, area_d1 = 0, area_d2 = 0; - BOOST_FOREACH(Geometry const& g, u) + for (Geometry const& g : u) { area_u += bg::area(g); } - BOOST_FOREACH(Geometry const& g, i) + for (Geometry const& g : i) { area_i += bg::area(g); } - BOOST_FOREACH(Geometry const& g, d1) + for (Geometry const& g : d1) { area_d1 += bg::area(g); } - BOOST_FOREACH(Geometry const& g, d2) + for (Geometry const& g : d2) { area_d2 += bg::area(g); } @@ -111,7 +108,7 @@ inline void test_assemble(std::string const& id, Geometry const& p, Geometry con : d2 ; - BOOST_FOREACH(Geometry const& geometry, v) + for (Geometry const& geometry : v) { mapper.map(geometry, linestyle + "stroke-width:3;stroke-linejoin:round;stroke-linecap:square;stroke-dasharray:12,12;stroke:rgb(255,0,0);"); @@ -123,7 +120,6 @@ inline void test_assemble(std::string const& id, Geometry const& p, Geometry con template inline bool int_ok(Polygon const& poly) { - typename bg::point_type::type const& pi = bg::interior_rings(poly)[0].front(); diff --git a/test/algorithms/overlay/dissolver.cpp b/test/algorithms/overlay/dissolver.cpp index c928fa7b3..2d8e28a0f 100644 --- a/test/algorithms/overlay/dissolver.cpp +++ b/test/algorithms/overlay/dissolver.cpp @@ -3,6 +3,10 @@ // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -46,7 +50,7 @@ void test_dissolve_plusmin(std::string const& caseid, Collection const& input, T positive_area = T(); T negative_area = T(); - BOOST_FOREACH(geometry_type const& geometry, output) + for (geometry_type const& geometry : output) { T a = bg::area(geometry); if (a > zero) @@ -74,17 +78,17 @@ void test_dissolve_plusmin(std::string const& caseid, Collection const& input, bg::svg_mapper mapper(svg, 500, 500); typedef typename boost::range_value::type value_type; - BOOST_FOREACH(value_type const& geometry, input) + for (value_type const& geometry : input) { mapper.add(geometry); } - BOOST_FOREACH(value_type const& geometry, input) + for (value_type const& geometry : input) { mapper.map(geometry, "opacity:0.6;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:0.5"); } - BOOST_FOREACH(geometry_type const& geometry, output) + for (geometry_type const& geometry : output) { mapper.map(geometry, bg::area(geometry) > 0 @@ -116,7 +120,7 @@ void test_geometry(std::string const& caseid, std::string const& wkt, typedef typename boost::range_value::type polygon_type; typedef typename bg::ring_type::type ring_type; std::vector rings; - BOOST_FOREACH(polygon_type const& polygon, multi_polygon) + for (polygon_type const& polygon : multi_polygon) { rings.push_back(bg::exterior_ring(polygon)); } diff --git a/test/algorithms/overlay/get_turn_info.cpp b/test/algorithms/overlay/get_turn_info.cpp index a70093de4..d8bb78356 100644 --- a/test/algorithms/overlay/get_turn_info.cpp +++ b/test/algorithms/overlay/get_turn_info.cpp @@ -3,31 +3,26 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017-2020. -// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) + #include #include -#include -#include - +#include +#include #include #include -#include -#include #include -// TEMP -#include - #if defined(TEST_WITH_SVG) # include #endif @@ -57,7 +52,7 @@ struct sub_range_from_points } private : - boost::array m_points; + Point m_points[3]; }; template diff --git a/test/algorithms/overlay/get_turns.cpp b/test/algorithms/overlay/get_turns.cpp index 5db074ab3..14b7b0f04 100644 --- a/test/algorithms/overlay/get_turns.cpp +++ b/test/algorithms/overlay/get_turns.cpp @@ -5,8 +5,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -122,7 +122,7 @@ struct test_get_turns "stroke:rgb(51,51,153);stroke-width:3"); int index = 0; - BOOST_FOREACH(turn_info const& turn, turns) + for (turn_info const& turn : turns) { mapper.map(turn.point, "fill:rgb(255,128,0);stroke:rgb(0,0,100);stroke-width:1"); diff --git a/test/algorithms/overlay/get_turns_linear_linear.cpp b/test/algorithms/overlay/get_turns_linear_linear.cpp index b6d0c8266..5cda27c34 100644 --- a/test/algorithms/overlay/get_turns_linear_linear.cpp +++ b/test/algorithms/overlay/get_turns_linear_linear.cpp @@ -5,9 +5,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014, 2015. -// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates. - +// This file was modified by Oracle on 2014-2021. +// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -215,7 +214,7 @@ void test_all() expected("muu++")); // 29.01.2015 - if ( BOOST_GEOMETRY_CONDITION((boost::is_same::value)) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { // FAILING - possibly wrong IPs test_geometry("LINESTRING(3 -0.6,0 -0.9)", @@ -308,7 +307,7 @@ void test_all() // determinants. // See also: https://svn.boost.org/trac/boost/ticket/8379 // https://github.com/boostorg/geometry/pull/259 - if ( BOOST_GEOMETRY_CONDITION((boost::is_same::value)) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { test_geometry("LINESTRING(0 0, 10 0, 20 1)", "LINESTRING(12 10, 13 0.3, 14 0.4, 15 0.5)", @@ -370,7 +369,7 @@ void test_all() //test_geometry("LINESTRING(0 0,2 2,3 3,4 4)", "LINESTRING(0 0,1 1,4 4)", "1FFF0FFF2"); - //if ( boost::is_same::value ) + //if ( std::is_same::value ) //{ // to_svg("LINESTRING(0 0,1 0,2 0,2.5 0,3 1)", "LINESTRING(0 0,2 0,2.5 0,3 1)", "test11.svg"); // to_svg("LINESTRING(0 0,1 0,2 0,2.5 0,3 1)", "LINESTRING(3 1,2.5 0,2 0,0 0)", "test12.svg"); @@ -520,7 +519,7 @@ void test_all() expected("tiu+=")("mui=+")); // parts of boundaries taken from union A/A buffer_mp1 - if ( BOOST_GEOMETRY_CONDITION((boost::is_same::value)) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { test_geometry("LINESTRING(6.95629520146761 5.415823381635526,6.989043790736545 5.209056926535316,7 5,6.989043790736547 4.790943073464693,6.956295201467611 4.584176618364482)", "LINESTRING(7.415823381635519 5.043704798532389,7.209056926535308 5.010956209263453,7.000000000000001 5,6.790943073464693 5.010956209263453,6.584176618364483 5.043704798532389)", diff --git a/test/algorithms/overlay/get_turns_linear_linear_sph.cpp b/test/algorithms/overlay/get_turns_linear_linear_sph.cpp index a6fdd1330..1de65088f 100644 --- a/test/algorithms/overlay/get_turns_linear_linear_sph.cpp +++ b/test/algorithms/overlay/get_turns_linear_linear_sph.cpp @@ -1,7 +1,7 @@ // Boost.Geometry // Unit Test -// Copyright (c) 2016, Oracle and/or its affiliates. +// Copyright (c) 2016-2021, 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, @@ -73,7 +73,7 @@ void test_all() "LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)", expected("tuu==")("ecc==")("mii++")("muu==")("mii++")("muu==")("mii++")); - if (BOOST_GEOMETRY_CONDITION((boost::is_same::value))) + if (BOOST_GEOMETRY_CONDITION((std::is_same::value))) { test_geometry("LINESTRING(-1 0,1 0,2 1.0004570537241201524198894179384922,3 2)", "LINESTRING(4 5,3 2,1 0,0 0)", @@ -223,7 +223,7 @@ void test_all() "LINESTRING(2 0,0 0,-10 0)", expected("tiu+=")("mui=+")); - if ( BOOST_GEOMETRY_CONDITION((boost::is_same::value)) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { test_geometry("LINESTRING(0 -1, 10 -1, 20 1)", "LINESTRING(12 10, 12.5 -0.50051443471392, 15 0, 17.5 0.50051443471392)", @@ -276,7 +276,7 @@ void test_all() //test_geometry("LINESTRING(0 0,2 2,3 3,4 4)", "LINESTRING(0 0,1 1,4 4)", "1FFF0FFF2"); - //if ( boost::is_same::value ) + //if ( std::is_same::value ) //{ // to_svg("LINESTRING(0 0,1 0,2 0,2.5 0,3 1)", "LINESTRING(0 0,2 0,2.5 0,3 1)", "test11.svg"); // to_svg("LINESTRING(0 0,1 0,2 0,2.5 0,3 1)", "LINESTRING(3 1,2.5 0,2 0,0 0)", "test12.svg"); diff --git a/test/algorithms/overlay/overlay.cpp b/test/algorithms/overlay/overlay.cpp index 5d3c04b21..ee1463216 100644 --- a/test/algorithms/overlay/overlay.cpp +++ b/test/algorithms/overlay/overlay.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017-2020. -// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021, 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,8 +18,6 @@ #include #include -#include - #if defined(TEST_WITH_SVG) # include #endif @@ -27,8 +25,9 @@ #include #include -#include +#include #include +#include #include //#include @@ -37,6 +36,8 @@ # include #endif +#include + #include "multi_overlay_cases.hpp" @@ -72,7 +73,7 @@ struct map_visitor { typedef typename boost::range_value::type turn_type; int index = 0; - BOOST_FOREACH(turn_type const& turn, turns) + for (turn_type const& turn : turns) { switch (phase) { @@ -129,7 +130,7 @@ struct map_visitor { typedef typename boost::range_value::type turn_type; int index = 0; - BOOST_FOREACH(turn_type const& turn, turns) + for (turn_type const& turn : turns) { if (turn.cluster_id >= 0) { diff --git a/test/algorithms/overlay/relative_order.cpp b/test/algorithms/overlay/relative_order.cpp index 8d2a5b47a..89fa77067 100644 --- a/test/algorithms/overlay/relative_order.cpp +++ b/test/algorithms/overlay/relative_order.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021, 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, @@ -16,13 +16,9 @@ #include - -#include - -#include - #include #include +#include #include #include @@ -31,8 +27,8 @@ # include #endif -#include #include +#include template diff --git a/test/algorithms/overlay/select_rings.cpp b/test/algorithms/overlay/select_rings.cpp index 89f43732f..2870691f5 100644 --- a/test/algorithms/overlay/select_rings.cpp +++ b/test/algorithms/overlay/select_rings.cpp @@ -2,8 +2,8 @@ // // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // -// This file was modified by Oracle on 2017-2020. -// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021 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, @@ -12,14 +12,10 @@ #include -#include -#include -#include -#include +#include #include -#include #include #include @@ -28,18 +24,15 @@ #include -#include - - template < typename Geometry1, typename Geometry2, bg::overlay_type OverlayType, - typename RingIdVector + typename RingId > void test_geometry(std::string const& wkt1, std::string const& wkt2, - RingIdVector const& expected_ids) + std::initializer_list const& expected_ids) { typedef bg::detail::overlay::ring_properties < @@ -68,8 +61,8 @@ void test_geometry(std::string const& wkt1, std::string const& wkt2, if (selected.size() <= expected_ids.size()) { - BOOST_AUTO(eit, expected_ids.begin()); - for(typename map_type::const_iterator it = selected.begin(); it != selected.end(); ++it, ++eit) + auto eit = expected_ids.begin(); + for (auto it = selected.begin(); it != selected.end(); ++it, ++eit) { bg::ring_identifier const ring_id = it->first; BOOST_CHECK_EQUAL(ring_id.source_index, eit->source_index); @@ -90,21 +83,19 @@ void test_all() test_geometry, bg::model::polygon

, bg::overlay_union>( winded[0], winded[1], - boost::assign::list_of - (rid(0,-1,-1)) - (rid(0,-1, 0)) - (rid(0,-1, 1)) - (rid(0,-1, 3)) - (rid(1,-1, 1)) - (rid(1,-1, 2))); + { rid(0,-1,-1), + rid(0,-1, 0), + rid(0,-1, 1), + rid(0,-1, 3), + rid(1,-1, 1), + rid(1,-1, 2) }); test_geometry, bg::model::polygon

, bg::overlay_intersection>( winded[0], winded[1], - boost::assign::list_of - (rid(0,-1, 2)) - (rid(1,-1,-1)) - (rid(1,-1, 0)) - (rid(1,-1, 3))); + { rid(0,-1, 2), + rid(1,-1,-1), + rid(1,-1, 0), + rid(1,-1, 3), }); } diff --git a/test/algorithms/overlay/self_intersection_points.cpp b/test/algorithms/overlay/self_intersection_points.cpp index 16b8ed24f..54d853ae2 100644 --- a/test/algorithms/overlay/self_intersection_points.cpp +++ b/test/algorithms/overlay/self_intersection_points.cpp @@ -5,8 +5,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2017-2020. -// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -77,7 +77,7 @@ static void test_self_intersection_points(std::string const& case_id, typedef typename bg::coordinate_type::type ct; ct zero = ct(); ct x = zero, y = zero; - BOOST_FOREACH(turn_info const& turn, turns) + for (turn_info const& turn : turns) { x += bg::get<0>(turn.point); y += bg::get<1>(turn.point); @@ -141,7 +141,7 @@ static void test_self_intersection_points(std::string const& case_id, mapper.map(geometry, "fill:rgb(255,255,128);stroke:rgb(0,0,0);stroke-width:1"); - BOOST_FOREACH(turn_info const& turn, turns) + for (turn_info const& turn : turns) { mapper.map(turn.point, "fill:rgb(255,128,0);stroke:rgb(0,0,100);stroke-width:1"); } diff --git a/test/algorithms/overlay/sort_by_side.cpp b/test/algorithms/overlay/sort_by_side.cpp index 2966d2a44..c8ecc6b97 100644 --- a/test/algorithms/overlay/sort_by_side.cpp +++ b/test/algorithms/overlay/sort_by_side.cpp @@ -4,8 +4,8 @@ // Copyright (c) 2016 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2017-2020. -// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021, 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, @@ -14,11 +14,11 @@ #include -#include +#include #include +#include #include -#include -#include +#include #include "multi_overlay_cases.hpp" @@ -31,7 +31,7 @@ std::string as_string(std::vector const& v) { std::stringstream out; bool first = true; - BOOST_FOREACH(T const& value, v) + for (T const& value : v) { out << (first ? "[" : " , ") << value; first = false; @@ -217,13 +217,11 @@ void test_sort_by_side(std::string const& case_id, // Define two small macro's to avoid repetitions of testcases/names etc -#define TEST_INT(caseid, exp) { (test_sort_by_side) \ - ( #caseid "_int", caseid[0], caseid[1], exp); } +#define TEST_INT(caseid, exp, ...) { (test_sort_by_side) \ + ( #caseid "_int", caseid[0], caseid[1], exp, __VA_ARGS__); } -#define TEST_UNION(caseid, exp) { (test_sort_by_side) \ - ( #caseid "_union", caseid[0], caseid[1], exp); } - -using boost::assign::list_of; +#define TEST_UNION(caseid, exp, ...) { (test_sort_by_side) \ + ( #caseid "_union", caseid[0], caseid[1], exp, __VA_ARGS__); } template void test_all() @@ -234,31 +232,31 @@ void test_all() // Selection of test cases having only one cluster - TEST_INT(case_64_multi, list_of(1)); - TEST_INT(case_72_multi, list_of(3)); - TEST_INT(case_107_multi, list_of(2)); - TEST_INT(case_123_multi, list_of(3)); - TEST_INT(case_124_multi, list_of(3)); - TEST_INT(case_recursive_boxes_10, list_of(2)); - TEST_INT(case_recursive_boxes_20, list_of(2)); - TEST_INT(case_recursive_boxes_21, list_of(1)); - TEST_INT(case_recursive_boxes_22, list_of(0)); + TEST_INT(case_64_multi, {1}); + TEST_INT(case_72_multi, {3}); + TEST_INT(case_107_multi, {2}); + TEST_INT(case_123_multi, {3}); + TEST_INT(case_124_multi, {3}); + TEST_INT(case_recursive_boxes_10, {2}); + TEST_INT(case_recursive_boxes_20, {2}); + TEST_INT(case_recursive_boxes_21, {2}); + TEST_INT(case_recursive_boxes_22, {0}); - TEST_UNION(case_recursive_boxes_46, list_of(2)(1)(2)(1)(1)(2)(1)); + TEST_UNION(case_recursive_boxes_46, {2, 1, 2, 1, 1, 2, 1}); - TEST_UNION(case_62_multi, list_of(2)); - TEST_UNION(case_63_multi, list_of(2)); - TEST_UNION(case_64_multi, list_of(1)); - TEST_UNION(case_107_multi, list_of(1)); - TEST_UNION(case_123_multi, list_of(1)); - TEST_UNION(case_124_multi, list_of(1)); - TEST_UNION(case_recursive_boxes_10, list_of(1)); - TEST_UNION(case_recursive_boxes_18, list_of(3)); - TEST_UNION(case_recursive_boxes_19, list_of(3)); - TEST_UNION(case_recursive_boxes_20, list_of(2)); - TEST_UNION(case_recursive_boxes_21, list_of(1)); - TEST_UNION(case_recursive_boxes_22, list_of(1)); - TEST_UNION(case_recursive_boxes_23, list_of(3)); + TEST_UNION(case_62_multi, {2}); + TEST_UNION(case_63_multi, {2}); + TEST_UNION(case_64_multi, {1}); + TEST_UNION(case_107_multi, {1}); + TEST_UNION(case_123_multi, {1}); + TEST_UNION(case_124_multi, {1}); + TEST_UNION(case_recursive_boxes_10, {1}); + TEST_UNION(case_recursive_boxes_18, {3}); + TEST_UNION(case_recursive_boxes_19, {3}); + TEST_UNION(case_recursive_boxes_20, {2}); + TEST_UNION(case_recursive_boxes_21, {1}); + TEST_UNION(case_recursive_boxes_22, {1}); + TEST_UNION(case_recursive_boxes_23, {3}); } int test_main(int, char* []) diff --git a/test/algorithms/overlay/sort_by_side_basic.cpp b/test/algorithms/overlay/sort_by_side_basic.cpp index a77f2e4dd..4ce87c724 100644 --- a/test/algorithms/overlay/sort_by_side_basic.cpp +++ b/test/algorithms/overlay/sort_by_side_basic.cpp @@ -4,8 +4,8 @@ // Copyright (c) 2017 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2017-2020. -// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates. +// This file was modified by Oracle on 2017-2021. +// Modifications copyright (c) 2017-2021, 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, @@ -14,18 +14,13 @@ #include -#include - -#include // for equals/within +#include #include #include -#include +#include #include -#include #include - -#include -#include +#include #if defined(TEST_WITH_SVG) #include "debug_sort_by_side_svg.hpp" @@ -40,7 +35,7 @@ std::string as_string(std::vector const& v) { std::stringstream out; bool first = true; - BOOST_FOREACH(T const& value, v) + for (T const& value : v) { out << (first ? "[" : " , ") << value; first = false; @@ -268,8 +263,6 @@ void test_basic(std::string const& case_id, expected_open_count, expected_max_rank, expected_right_count); } -using boost::assign::list_of; - template void test_all() { @@ -277,67 +270,67 @@ void test_all() "MULTIPOLYGON(((0 2,1 2,1 1,0 1,0 2)))", "MULTIPOLYGON(((1 0,1 1,2 1,2 0,1, 0)))", "POINT(1 1)", "POINT(1 0)", - 2, 3, list_of(-1)(1)(-1)(1)); + 2, 3, {-1, 1, -1, 1}); test_basic("dup1", "MULTIPOLYGON(((0 2,1 2,1 1,0 1,0 2)))", "MULTIPOLYGON(((1 0,1 1,2 1,2 0,1, 0)),((0 2,1 2,1 1,0 1,0 2)))", "POINT(1 1)", "POINT(1 0)", - 2, 3, list_of(-1)(1)(-1)(2)); + 2, 3, {-1, 1, -1, 2}); test_basic("dup2", "MULTIPOLYGON(((0 2,1 2,1 1,0 1,0 2)),((1 0,1 1,2 1,2 0,1, 0)))", "MULTIPOLYGON(((1 0,1 1,2 1,2 0,1, 0)))", "POINT(1 1)", "POINT(1 0)", - 2, 3, list_of(-1)(2)(-1)(1)); + 2, 3, {-1, 2, -1, 1}); test_basic("dup3", "MULTIPOLYGON(((0 2,1 2,1 1,0 1,0 2)),((1 0,1 1,2 1,2 0,1, 0)))", "MULTIPOLYGON(((1 0,1 1,2 1,2 0,1, 0)),((0 2,1 2,1 1,0 1,0 2)))", "POINT(1 1)", "POINT(1 0)", - 2, 3, list_of(-1)(2)(-1)(2)); + 2, 3, {-1, 2, -1, 2}); test_basic("threequart1", "MULTIPOLYGON(((0 2,1 2,1 1,0 1,0 2)),((1 0,1 1,2 1,2 0,1, 0)))", "MULTIPOLYGON(((1 2,2 2,2 1,1 1,1 2)))", "POINT(1 1)", "POINT(1 0)", - 1, 3, list_of(-1)(1)(1)(1)); + 1, 3, {-1, 1, 1, 1}); test_basic("threequart2", "MULTIPOLYGON(((0 2,1 2,1 1,0 1,0 2)),((1 0,1 1,2 1,2 0,1, 0)))", "MULTIPOLYGON(((1 2,2 2,2 1,1 1,1 2)),((2 0,1 0,1 1,2 0)))", "POINT(1 1)", "POINT(1 0)", - 1, 4, list_of(-1)(2)(1)(1)(1)); + 1, 4, {-1, 2, 1, 1, 1}); test_basic("threequart3", "MULTIPOLYGON(((0 2,1 2,1 1,0 1,0 2)),((1 0,1 1,2 1,2 0,1, 0)))", "MULTIPOLYGON(((1 2,2 2,2 1,1 1,1 2)),((2 0,1 0,1 1,2 0)),((0 1,0 2,1 1,0 1)))", "POINT(1 1)", "POINT(1 0)", - 1, 5, list_of(-1)(2)(1)(1)(-1)(2)); + 1, 5, {-1, 2, 1, 1, -1, 2}); test_basic("full1", "MULTIPOLYGON(((0 2,1 2,1 1,0 1,0 2)),((1 0,1 1,2 1,2 0,1, 0)))", "MULTIPOLYGON(((1 2,2 2,2 1,1 1,1 2)),((0 0,0 1,1 1,1 0,0 0)))", "POINT(1 1)", "POINT(1 0)", - 0, 3, list_of(1)(1)(1)(1)); + 0, 3, {1, 1, 1, 1}); test_basic("hole1", "MULTIPOLYGON(((0 0,0 3,2 3,2 2,3 2,3 0,0 0),(1 1,2 1,2 2,1 2,1 1)),((4 2,3 2,3 3,4 3,4 2)))", "MULTIPOLYGON(((1 0,1 1,2 1,2 2,1 2,1 4,4 4,4 0,1, 0),(3 2,3 3,2 3,2 2,3 2)))", "POINT(1 2)", "POINT(2 2)", - 1, 2, list_of(-1)(2)(1)); + 1, 2, {-1, 2, 1}); test_basic("hole2", "MULTIPOLYGON(((0 0,0 3,2 3,2 2,3 2,3 0,0 0),(1 1,2 1,2 2,1 2,1 1)),((4 2,3 2,3 3,4 3,4 2)))", "MULTIPOLYGON(((1 0,1 1,2 1,2 2,1 2,1 4,4 4,4 0,1, 0),(3 2,3 3,2 3,2 2,3 2)))", "POINT(2 2)", "POINT(2 1)", - 2, 3, list_of(-1)(2)(-1)(2)); + 2, 3, {-1, 2, -1, 2}); test_basic("hole3", "MULTIPOLYGON(((0 0,0 3,2 3,2 2,3 2,3 0,0 0),(1 1,2 1,2 2,1 2,1 1)),((4 2,3 2,3 3,4 3,4 2)))", "MULTIPOLYGON(((1 0,1 1,2 1,2 2,1 2,1 4,4 4,4 0,1, 0),(3 2,3 3,2 3,2 2,3 2)))", "POINT(3 2)", "POINT(2 2)", - 1, 3, list_of(-1)(2)(-1)(2)); + 1, 3, {-1, 2, -1, 2}); } diff --git a/test/algorithms/overlay/split_rings.cpp b/test/algorithms/overlay/split_rings.cpp index 00cf9f85b..90704de0e 100644 --- a/test/algorithms/overlay/split_rings.cpp +++ b/test/algorithms/overlay/split_rings.cpp @@ -5,6 +5,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -62,7 +66,7 @@ struct test_split_rings mapper.map(geometry, "fill:rgb(255,255,128);stroke:rgb(0,0,0);stroke-width:1"); - BOOST_FOREACH(ring_type const& ring, rings) + for (ring_type const& ring : rings) { std::string style = "opacity:0.6;fill:rgb"; std::string color = bg::area(ring) > 0 ? "(255,0,0)" : "(0,0,255)"; diff --git a/test/algorithms/overlay/traverse.cpp b/test/algorithms/overlay/traverse.cpp index 2e4f801cc..50bd474fc 100644 --- a/test/algorithms/overlay/traverse.cpp +++ b/test/algorithms/overlay/traverse.cpp @@ -3,6 +3,10 @@ // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -17,8 +21,6 @@ #include #include -#include - #include @@ -34,32 +36,28 @@ # define BOOST_GEOMETRY_DEBUG_IDENTIFIER #endif -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include - #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include - #if defined(TEST_WITH_SVG) # include #endif +#include + #include #include @@ -143,10 +141,10 @@ struct test_traverse //std::cout << bg::area(g1) << " " << bg::area(g2) << std::endl; #endif - typedef typename bg::strategy::side::services::default_strategy - < - typename bg::cs_tag::type - >::type side_strategy_type; + typename bg::strategy::intersection::services::default_strategy + < + typename bg::cs_tag::type + >::type strategy; typedef typename bg::point_type::type point_type; typedef typename bg::rescale_policy_type::type @@ -162,15 +160,11 @@ struct test_traverse > turn_info; std::vector turns; - bg::detail::overlay::operation_type const op = - OverlayType == bg::overlay_union - ? bg::detail::overlay::operation_union - : bg::detail::overlay::operation_intersection; + std::map clusters; bg::detail::get_turns::no_interrupt_policy policy; - bg::get_turns(g1, g2, rescale_policy, turns, policy); - bg::enrich_intersection_points(turns, op, - g1, g2, rescale_policy, side_strategy_type()); + bg::get_turns(g1, g2, strategy, rescale_policy, turns, policy); + bg::enrich_intersection_points(turns, clusters, g1, g2, rescale_policy, strategy); typedef bg::model::ring::type> ring_type; typedef std::vector out_vector; @@ -178,11 +172,13 @@ struct test_traverse bg::detail::overlay::overlay_null_visitor visitor; + // TODO: this function requires additional arguments bg::detail::overlay::traverse < Reverse1, Reverse2, - G1, G2 - >::apply(g1, g2, op, rescale_policy, turns, v, visitor); + G1, G2, + OverlayType + >::apply(g1, g2, strategy, rescale_policy, turns, v, visitor); // Check number of resulting rings BOOST_CHECK_MESSAGE(expected_count == boost::size(v), @@ -196,7 +192,7 @@ struct test_traverse // Check total area of resulting rings typename bg::default_area_result::type total_area = 0; - BOOST_FOREACH(ring_type const& ring, v) + for (ring_type const& ring : v) { total_area += bg::area(ring); //std::cout << bg::wkt(ring) << std::endl; @@ -225,7 +221,7 @@ struct test_traverse "stroke:rgb(51,51,153);stroke-width:3"); // Traversal rings in magenta outline/red fill -> over blue/green this gives brown - BOOST_FOREACH(ring_type const& ring, v) + for (ring_type const& ring : v) { mapper.map(ring, "fill-opacity:0.2;stroke-opacity:0.4;fill:rgb(255,0,0);" "stroke:rgb(255,0,255);stroke-width:8"); @@ -239,7 +235,7 @@ struct test_traverse int index = 0; int const margin = 5; - BOOST_FOREACH(turn_info const& turn, turns) + for (turn_info const& turn : turns) { int lineheight = 8; mapper.map(turn.point, "fill:rgb(255,128,0);" @@ -771,8 +767,7 @@ void test_all(bool test_self_tangencies = true, bool test_mixed = false) } */ - static const bool is_float - = boost::is_same::value; + static const bool is_float = std::is_same::value; static const double float_might_deviate_more = is_float ? 0.1 : 0.001; // In some cases up to 1 promille permitted diff --git a/test/algorithms/overlay/traverse_ccw.cpp b/test/algorithms/overlay/traverse_ccw.cpp index f93980860..a3f643606 100644 --- a/test/algorithms/overlay/traverse_ccw.cpp +++ b/test/algorithms/overlay/traverse_ccw.cpp @@ -3,6 +3,10 @@ // Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -13,11 +17,11 @@ #include #include -#include - #include -#include +#include +#include +#include #include #include #include @@ -26,14 +30,12 @@ # include #endif -#include #include #include template -struct rev : boost::mpl::if_c::value == bg::counterclockwise, boost::true_type, boost::false_type>::type -{}; +using rev = bg::util::bool_constant::value == bg::counterclockwise>; template inline typename bg::coordinate_type::type @@ -89,7 +91,7 @@ intersect(Geometry1 const& g1, Geometry2 const& g2, std::string const& name, >::apply(g1, g2, op, rescale_policy, turns, v); typename bg::coordinate_type::type result = 0.0; - BOOST_FOREACH(ring_type& ring, v) + for (ring_type& ring : v) { result += bg::area(ring); } @@ -117,7 +119,7 @@ intersect(Geometry1 const& g1, Geometry2 const& g2, std::string const& name, "stroke:rgb(51,51,153);stroke-width:3"); // Traversal rings in magenta/light yellow fill - BOOST_FOREACH(ring_type const& ring, v) + for (ring_type const& ring : v) { mapper.map(ring, "fill-opacity:0.3;stroke-opacity:0.4;fill:rgb(255,255,0);" "stroke:rgb(255,0,255);stroke-width:8"); @@ -132,7 +134,7 @@ intersect(Geometry1 const& g1, Geometry2 const& g2, std::string const& name, int const lineheight = 10; int const margin = 5; - BOOST_FOREACH(turn_info const& turn, turns) + for (turn_info const& turn : turns) { mapper.map(turn.point, "fill:rgb(255,128,0);" "stroke:rgb(0,0,0);stroke-width:1", 3); diff --git a/test/algorithms/point_on_surface.cpp b/test/algorithms/point_on_surface.cpp index 7ee5eb880..048635ecb 100644 --- a/test/algorithms/point_on_surface.cpp +++ b/test/algorithms/point_on_surface.cpp @@ -6,9 +6,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2015. -// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates. - +// This file was modified by Oracle on 2014-2021. +// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -101,7 +100,7 @@ void test_geometry(std::string const& case_id, Geometry const& geometry, double // Top (red/magenta) mapper.map(top_points, "stroke:rgb(255,0,0);stroke-width:2"); - BOOST_FOREACH(intruder_type const& intruder, top_intruders) + for (intruder_type const& intruder : top_intruders) { mapper.map(intruder, "stroke:rgb(255,0,255);stroke-width:2"); } @@ -111,7 +110,7 @@ void test_geometry(std::string const& case_id, Geometry const& geometry, double //// Right (blue/cyan) // (mostly commented, makes the picture less clear) //mapper.map(right_points, "stroke:rgb(0,0,255);stroke-width:2"); - //BOOST_FOREACH(intruder_type const& intruder, right_intruders) + //for (intruder_type const& intruder : right_intruders) //{ // mapper.map(intruder, "stroke:rgb(0,255,255);stroke-width:2"); //} diff --git a/test/algorithms/relate/nan_cases.hpp b/test/algorithms/relate/nan_cases.hpp index 24306202d..bbd888831 100644 --- a/test/algorithms/relate/nan_cases.hpp +++ b/test/algorithms/relate/nan_cases.hpp @@ -1,7 +1,6 @@ // Boost.Geometry -// Copyright (c) 2015 Oracle and/or its affiliates. - +// Copyright (c) 2015-2021 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, @@ -14,7 +13,6 @@ #include #include -#include template struct pusher @@ -125,6 +123,6 @@ struct is_nan_case_supported { typedef typename bg::coordinate_type::type coord_t; - static const bool value = boost::is_same::value + static const bool value = std::is_same::value && std::numeric_limits::has_quiet_NaN; }; diff --git a/test/algorithms/relate/relate_areal_areal.cpp b/test/algorithms/relate/relate_areal_areal.cpp index 739a37a35..bee45efa9 100644 --- a/test/algorithms/relate/relate_areal_areal.cpp +++ b/test/algorithms/relate/relate_areal_areal.cpp @@ -2,9 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. - +// This file was modified by Oracle on 2013-2021. +// Modifications copyright (c) 2013-2021 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,8 +18,9 @@ template void test_polygon_polygon() { - typedef bg::model::polygon

poly; - typedef bg::model::ring

ring; + using coord_t = typename bg::coordinate_type

::type; + using poly = bg::model::polygon

; + using ring = bg::model::ring

; // touching test_geometry("POLYGON((0 0,0 10,10 10,10 0,0 0))", @@ -306,8 +306,7 @@ void test_polygon_polygon() "212101212"); } - if ( BOOST_GEOMETRY_CONDITION(( - boost::is_same::type, double>::value )) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { // original - assertion for CCW //"POLYGON((-0.593220338983050821113352 -8.05084745762711939676137,1.14285714285714279370154 -4,1.50731707317073171381594 1.10243902439024443751237,1.73758865248226967992196 1.37588652482269591104114,1.21739130434782616418943 -3.82608695652173924628414,2 -2,2 1.68750000000000044408921,2.35384615384615436539661 2.10769230769230775379697,2 2.16666666666666651863693,2 4,1.81967213114754100544701 2.1967213114754100544701,1.5882352941176469673934 2.2352941176470588757752,1.8148148148148146585612 5.4074074074074074403029,-0.538461538461538546940233 4.23076923076923083755219,-1.76510067114094004736558 2.89261744966443012927471,-1.64864864864864868465588 2.7567567567567570208098,-1.83962264150943455298659 2.81132075471698161805989,-1.84337349397590433142113 2.80722891566265086993326,-2.14285714285714279370154 2.85714285714285720629846,-2.11111111111111116045436 2.88888888888888883954564,-2.87234042553191448732264 3.10638297872340407579372,-2.91803278688524558859285 3.4262295081967208965068,-3.1733333333333324510761 3.26666666666666660745477,-2.99999999999999822364316 3.14285714285714234961233,-3.25490196078431326398572 3.21568627450980359938626,-3.47368421052631504153396 3.07894736842105265495206,-7.32000000000000028421709 3.72000000000000019539925,-7.54716981132075481752963 3.62264150943396234794136,-7.75 3.79166666666666651863693,-7.79999999999999982236432 3.79999999999999982236432,-7.59999999999999964472863 3.60000000000000008881784,-8.8556701030927822415606 3.06185567010309300783888,-8.82945736434108674473009 2.8914728682170549589614,-7.73333333333333339254523 2.193939393939393855959,-8 2,-5.94736842105263185942476 -1.42105263157894645686952,-5.32558139534883689947264 -0.488372093023255016142059,-5.85714285714285765038767 1.00000000000000066613381,-4.78723404255319184841255 0.319148936170212838003835,-5.32558139534883689947264 -0.488372093023255016142059,-4.74019607843137258385013 -2.12745098039215774221589,-3.17647058823529437887601 -0.705882352941176627325603,-2.93103448275862055183438 -0.862068965517241436735674,-3 -1,-4.57894736842105309904127 -2.57894736842105265495206,-4.47887323943661996850096 -2.85915492957746497637572,-7.58620689655172419918472 -5.18965517241379359347775,-7.52525252525252508206677 -5.5858585858585865224768,-4.18644067796610119813749 -3.67796610169491522412955,-3.44041450777202051369841 -5.76683937823834202873741,-3.73611111111111116045436 -6.56944444444444464181743,-2.8823529411764705621124 -7.7647058823529411242248,-2.88235294117647100620161 -7.7647058823529411242248,-0.593220338983050821113352 -8.05084745762711939676137),(1.66666666666666696272614 1.59999999999999875655021,1.43749999999999911182158 1.8750000000000002220446,0.0869565217391310429917439 2.26086956521739113057379,0.466666666666667118157363 2.60606060606060552231611,1.04878048780487764801705 2.34146341463414664474385,1.43749999999999911182158 1.8750000000000002220446,1.56756756756756754356275 1.83783783783783771781373,1.66666666666666696272614 1.59999999999999875655021))" diff --git a/test/algorithms/relate/relate_linear_areal_sph.cpp b/test/algorithms/relate/relate_linear_areal_sph.cpp index e3034301c..630b0a0f7 100644 --- a/test/algorithms/relate/relate_linear_areal_sph.cpp +++ b/test/algorithms/relate/relate_linear_areal_sph.cpp @@ -1,8 +1,7 @@ // Boost.Geometry // Unit Test -// Copyright (c) 2016, Oracle and/or its affiliates. - +// Copyright (c) 2016-2021, 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, @@ -287,8 +286,7 @@ void test_multi_linestring_polygon() "POLYGON((5 0,0 -5,-5 0,0 5,5 0))", "1F10F0212"); - if ( BOOST_GEOMETRY_CONDITION(( - boost::is_same::value )) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { // assertion failure in 1.57 test_geometry("MULTILINESTRING((-0.59322033898305082 -8.0508474576271194,-2.882352941176471 -7.7647058823529411,-2.8823529411764706 -7.7647058823529411,-3.7361111111111112 -6.5694444444444446,-3.4404145077720205 -5.766839378238342,-4.1864406779661012 -3.6779661016949152,-7.5252525252525251 -5.5858585858585865,-7.5862068965517242 -5.1896551724137936,-4.47887323943662 -2.859154929577465,-4.5789473684210531 -2.5789473684210527,-3 -1,-2.9310344827586206 -0.86206896551724144,-3.1764705882352944 -0.70588235294117663,-4.7401960784313726 -2.1274509803921577,-5.3255813953488369 -0.48837209302325502,-4.7872340425531918 0.31914893617021284,-5.8571428571428577 1.0000000000000007,-5.3255813953488369 -0.48837209302325502,-5.9473684210526319 -1.4210526315789465,-8 2,-7.7333333333333334 2.1939393939393939,-8.8294573643410867 2.891472868217055,-8.8556701030927822 3.061855670103093,-7.5999999999999996 3.6000000000000001,-7.7999999999999998 3.7999999999999998,-7.75 3.7916666666666665,-7.5471698113207548 3.6226415094339623,-7.3200000000000003 3.7200000000000002,-3.473684210526315 3.0789473684210527,-3.2549019607843133 3.2156862745098036,-2.9999999999999982 3.1428571428571423,-3.1733333333333325 3.2666666666666666,-2.9180327868852456 3.4262295081967209,-2.8723404255319145 3.1063829787234041,-2.1111111111111112 2.8888888888888888,-2.1428571428571428 2.8571428571428572,-1.8433734939759043 2.8072289156626509,-1.8396226415094346 2.8113207547169816,-1.6486486486486487 2.756756756756757,-1.76510067114094 2.8926174496644301,-0.53846153846153855 4.2307692307692308,1.8148148148148147 5.4074074074074074,1.588235294117647 2.2352941176470589,1.819672131147541 2.1967213114754101,2 4,2 2.1666666666666665,2.3538461538461544 2.1076923076923078,2 1.6875000000000004,2 -2,1.2173913043478262 -3.8260869565217392,1.7375886524822697 1.3758865248226959,1.5073170731707317 1.1024390243902444,1.1428571428571428 -4,-0.59322033898305082 -8.0508474576271194),(1.666666666666667 1.5999999999999988,1.5675675675675675 1.8378378378378377,1.4374999999999991 1.8750000000000002,1.0487804878048776 2.3414634146341466,0.46666666666666712 2.6060606060606055,0.086956521739131043 2.2608695652173911,1.4374999999999991 1.8750000000000002,1.666666666666667 1.5999999999999988))", diff --git a/test/algorithms/relate/relate_linear_linear.cpp b/test/algorithms/relate/relate_linear_linear.cpp index d109e8b92..0dbf139c1 100644 --- a/test/algorithms/relate/relate_linear_linear.cpp +++ b/test/algorithms/relate/relate_linear_linear.cpp @@ -2,9 +2,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates. - +// This file was modified by Oracle on 2013-2021. +// Modifications copyright (c) 2013-2021 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 +18,8 @@ template void test_linestring_linestring() { - typedef bg::model::linestring

ls; + using coord_t = typename bg::coordinate_type

::type; + using ls = bg::model::linestring

; test_geometry("LINESTRING(0 0, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 3 2)", "1FFF0FFF2"); test_geometry("LINESTRING(0 0,3 2)", "LINESTRING(0 0, 2 2, 3 2)", "FF1F0F1F2"); @@ -185,8 +185,7 @@ void test_linestring_linestring() // Point/Point //test_geometry("LINESTRING(0 0)", "LINESTRING(0 0)", "0FFFFFFF2"); - if ( BOOST_GEOMETRY_CONDITION( - boost::is_floating_point::type>::value ) ) + if ( BOOST_GEOMETRY_CONDITION(std::is_floating_point::value) ) { // https://svn.boost.org/trac/boost/ticket/10904 // very small segments @@ -198,8 +197,7 @@ void test_linestring_linestring() "FF1F00102", "F0FFFF102"); // on some platforms the first Linestring may be detected as degenerated to Point } - if ( BOOST_GEOMETRY_CONDITION(( - boost::is_same::type, double>::value )) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { // detected as collinear test_geometry("LINESTRING(1 -10, 3.069359e+307 3.069359e+307)", @@ -247,8 +245,9 @@ void test_linestring_linestring() template void test_linestring_multi_linestring() { - typedef bg::model::linestring

ls; - typedef bg::model::multi_linestring mls; + using coord_t = typename bg::coordinate_type

::type; + using ls = bg::model::linestring

; + using mls = bg::model::multi_linestring; // LS disjoint test_geometry("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,2 0),(1 1,2 1))", "101FF0102"); @@ -347,7 +346,7 @@ void test_linestring_multi_linestring() "10FF0F102"); // | // | - if ( BOOST_GEOMETRY_CONDITION(boost::is_floating_point::type>::value) ) + if ( BOOST_GEOMETRY_CONDITION(std::is_floating_point::value) ) { // related to https://svn.boost.org/trac/boost/ticket/10904 test_geometry("LINESTRING(-2305843009213693956 4611686018427387906, -33 -92, 78 83)", @@ -386,8 +385,9 @@ void test_linestring_multi_linestring() template void test_multi_linestring_multi_linestring() { - typedef bg::model::linestring

ls; - typedef bg::model::multi_linestring mls; + using coord_t = typename bg::coordinate_type

::type; + using ls = bg::model::linestring

; + using mls = bg::model::multi_linestring; test_geometry("MULTILINESTRING((0 0,0 0,18 0,18 0,19 0,19 0,19 0,30 0,30 0))", "MULTILINESTRING((0 10,5 0,20 0,20 0,30 0))", @@ -415,8 +415,7 @@ void test_multi_linestring_multi_linestring() "MULTILINESTRING((5 5,0 5),(5 5,5 0),(10 10,10 5,5 5,5 10,10 10))", "10FFFFFF2"); - if ( BOOST_GEOMETRY_CONDITION(( - boost::is_same::type, double>::value )) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { // assertion failure in 1.57 test_geometry("MULTILINESTRING((-0.59322033898305082 -8.0508474576271194,-2.882352941176471 -7.7647058823529411,-2.8823529411764706 -7.7647058823529411,-3.7361111111111112 -6.5694444444444446,-3.4404145077720205 -5.766839378238342,-4.1864406779661012 -3.6779661016949152,-7.5252525252525251 -5.5858585858585865,-7.5862068965517242 -5.1896551724137936,-4.47887323943662 -2.859154929577465,-4.5789473684210531 -2.5789473684210527,-3 -1,-2.9310344827586206 -0.86206896551724144,-3.1764705882352944 -0.70588235294117663,-4.7401960784313726 -2.1274509803921577,-5.3255813953488369 -0.48837209302325502,-4.7872340425531918 0.31914893617021284,-5.8571428571428577 1.0000000000000007,-5.3255813953488369 -0.48837209302325502,-5.9473684210526319 -1.4210526315789465,-8 2,-7.7333333333333334 2.1939393939393939,-8.8294573643410867 2.891472868217055,-8.8556701030927822 3.061855670103093,-7.5999999999999996 3.6000000000000001,-7.7999999999999998 3.7999999999999998,-7.75 3.7916666666666665,-7.5471698113207548 3.6226415094339623,-7.3200000000000003 3.7200000000000002,-3.473684210526315 3.0789473684210527,-3.2549019607843133 3.2156862745098036,-2.9999999999999982 3.1428571428571423,-3.1733333333333325 3.2666666666666666,-2.9180327868852456 3.4262295081967209,-2.8723404255319145 3.1063829787234041,-2.1111111111111112 2.8888888888888888,-2.1428571428571428 2.8571428571428572,-1.8433734939759043 2.8072289156626509,-1.8396226415094346 2.8113207547169816,-1.6486486486486487 2.756756756756757,-1.76510067114094 2.8926174496644301,-0.53846153846153855 4.2307692307692308,1.8148148148148147 5.4074074074074074,1.588235294117647 2.2352941176470589,1.819672131147541 2.1967213114754101,2 4,2 2.1666666666666665,2.3538461538461544 2.1076923076923078,2 1.6875000000000004,2 -2,1.2173913043478262 -3.8260869565217392,1.7375886524822697 1.3758865248226959,1.5073170731707317 1.1024390243902444,1.1428571428571428 -4,-0.59322033898305082 -8.0508474576271194),(1.666666666666667 1.5999999999999988,1.5675675675675675 1.8378378378378377,1.4374999999999991 1.8750000000000002,1.0487804878048776 2.3414634146341466,0.46666666666666712 2.6060606060606055,0.086956521739131043 2.2608695652173911,1.4374999999999991 1.8750000000000002,1.666666666666667 1.5999999999999988))", diff --git a/test/algorithms/relate/relate_linear_linear_sph.cpp b/test/algorithms/relate/relate_linear_linear_sph.cpp index ec472c68e..b0c9ac226 100644 --- a/test/algorithms/relate/relate_linear_linear_sph.cpp +++ b/test/algorithms/relate/relate_linear_linear_sph.cpp @@ -1,8 +1,7 @@ // Boost.Geometry // Unit Test -// Copyright (c) 2016, Oracle and/or its affiliates. - +// Copyright (c) 2016-2021, 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, @@ -16,7 +15,8 @@ template void test_linestring_linestring() { - typedef bg::model::linestring

ls; + using coord_t = typename bg::coordinate_type

::type; + using ls = bg::model::linestring

; test_geometry("LINESTRING(0 0, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 3 2)", "1FFF0FFF2"); test_geometry("LINESTRING(0 0,3 2)", "LINESTRING(0 0, 2 2, 3 2)", "FF1F0F1F2"); @@ -182,8 +182,7 @@ void test_linestring_linestring() // Point/Point //test_geometry("LINESTRING(0 0)", "LINESTRING(0 0)", "0FFFFFFF2"); - if ( BOOST_GEOMETRY_CONDITION( - boost::is_floating_point::type>::value ) ) + if ( BOOST_GEOMETRY_CONDITION(std::is_floating_point::value) ) { // https://svn.boost.org/trac/boost/ticket/10904 // very small segments @@ -195,8 +194,7 @@ void test_linestring_linestring() "*********"); // TODO: be more specific with the result } - if ( BOOST_GEOMETRY_CONDITION(( - boost::is_same::type, double>::value )) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { // detected as collinear test_geometry("LINESTRING(1 -10, 3.069359e+307 3.069359e+307)", @@ -244,8 +242,9 @@ void test_linestring_linestring() template void test_linestring_multi_linestring() { - typedef bg::model::linestring

ls; - typedef bg::model::multi_linestring mls; + using coord_t = typename bg::coordinate_type

::type; + using ls = bg::model::linestring

; + using mls = bg::model::multi_linestring; // LS disjoint test_geometry("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,2 0),(1 1,2 1))", "101FF0102"); @@ -344,7 +343,7 @@ void test_linestring_multi_linestring() "10FF0F102"); // | // | - if ( BOOST_GEOMETRY_CONDITION(boost::is_floating_point::type>::value) ) + if ( BOOST_GEOMETRY_CONDITION(std::is_floating_point::value) ) { // related to https://svn.boost.org/trac/boost/ticket/10904 test_geometry("LINESTRING(-2305843009213693956 4611686018427387906, -33 -92, 78 83)", @@ -389,8 +388,9 @@ void test_linestring_multi_linestring() template void test_multi_linestring_multi_linestring() { - typedef bg::model::linestring

ls; - typedef bg::model::multi_linestring mls; + using coord_t = typename bg::coordinate_type

::type; + using ls = bg::model::linestring

; + using mls = bg::model::multi_linestring; test_geometry("MULTILINESTRING((0 0,0 0,18 0,18 0,19 0,19 0,19 0,30 0,30 0))", "MULTILINESTRING((0 10,5 0,20 0,20 0,30 0))", @@ -418,8 +418,7 @@ void test_multi_linestring_multi_linestring() "MULTILINESTRING((5 5.0190018174896416,0 5),(5 5.0190018174896416,5 0),(10 10,10 5,5 5.0190018174896416,5 10,10 10))", "10FFFFFF2"); - if ( BOOST_GEOMETRY_CONDITION(( - boost::is_same::type, double>::value )) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { // assertion failure in 1.57 test_geometry("MULTILINESTRING((-0.59322033898305082 -8.0508474576271194,-2.882352941176471 -7.7647058823529411,-2.8823529411764706 -7.7647058823529411,-3.7361111111111112 -6.5694444444444446,-3.4404145077720205 -5.766839378238342,-4.1864406779661012 -3.6779661016949152,-7.5252525252525251 -5.5858585858585865,-7.5862068965517242 -5.1896551724137936,-4.47887323943662 -2.859154929577465,-4.5789473684210531 -2.5789473684210527,-3 -1,-2.9310344827586206 -0.86206896551724144,-3.1764705882352944 -0.70588235294117663,-4.7401960784313726 -2.1274509803921577,-5.3255813953488369 -0.48837209302325502,-4.7872340425531918 0.31914893617021284,-5.8571428571428577 1.0000000000000007,-5.3255813953488369 -0.48837209302325502,-5.9473684210526319 -1.4210526315789465,-8 2,-7.7333333333333334 2.1939393939393939,-8.8294573643410867 2.891472868217055,-8.8556701030927822 3.061855670103093,-7.5999999999999996 3.6000000000000001,-7.7999999999999998 3.7999999999999998,-7.75 3.7916666666666665,-7.5471698113207548 3.6226415094339623,-7.3200000000000003 3.7200000000000002,-3.473684210526315 3.0789473684210527,-3.2549019607843133 3.2156862745098036,-2.9999999999999982 3.1428571428571423,-3.1733333333333325 3.2666666666666666,-2.9180327868852456 3.4262295081967209,-2.8723404255319145 3.1063829787234041,-2.1111111111111112 2.8888888888888888,-2.1428571428571428 2.8571428571428572,-1.8433734939759043 2.8072289156626509,-1.8396226415094346 2.8113207547169816,-1.6486486486486487 2.756756756756757,-1.76510067114094 2.8926174496644301,-0.53846153846153855 4.2307692307692308,1.8148148148148147 5.4074074074074074,1.588235294117647 2.2352941176470589,1.819672131147541 2.1967213114754101,2 4,2 2.1666666666666665,2.3538461538461544 2.1076923076923078,2 1.6875000000000004,2 -2,1.2173913043478262 -3.8260869565217392,1.7375886524822697 1.3758865248226959,1.5073170731707317 1.1024390243902444,1.1428571428571428 -4,-0.59322033898305082 -8.0508474576271194),(1.666666666666667 1.5999999999999988,1.5675675675675675 1.8378378378378377,1.4374999999999991 1.8750000000000002,1.0487804878048776 2.3414634146341466,0.46666666666666712 2.6060606060606055,0.086956521739131043 2.2608695652173911,1.4374999999999991 1.8750000000000002,1.666666666666667 1.5999999999999988))", diff --git a/test/algorithms/relate/test_relate.hpp b/test/algorithms/relate/test_relate.hpp index 859d29ade..bf8b550ee 100644 --- a/test/algorithms/relate/test_relate.hpp +++ b/test/algorithms/relate/test_relate.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2021. +// Modifications copyright (c) 2013-2021 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, @@ -17,18 +17,11 @@ #include -#include #include #include -#include #include -#include - #include - -#include -#include -#include +#include namespace bgdr = bg::detail::relate; @@ -190,7 +183,7 @@ void check_geometry(Geometry1 const& geometry1, // brake the expected output std::string expected_interrupt = expected1; bool changed = false; - BOOST_FOREACH(char & c, expected_interrupt) + for (char & c : expected_interrupt) { if ( c >= '0' && c <= '9' ) { diff --git a/test/algorithms/set_operations/difference/difference.cpp b/test/algorithms/set_operations/difference/difference.cpp index 0565f47aa..d6fda96d1 100644 --- a/test/algorithms/set_operations/difference/difference.cpp +++ b/test/algorithms/set_operations/difference/difference.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015, 2016. -// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2021. +// Modifications copyright (c) 2015-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 @@ -293,7 +293,7 @@ void test_all() 1, 61, 10.2717, 1, 61, 10.2717); - if ( BOOST_GEOMETRY_CONDITION((boost::is_same::value)) ) + if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { test_one("buffer_mp2", buffer_mp2[0], buffer_mp2[1], diff --git a/test/algorithms/set_operations/difference/difference_areal_linear.cpp b/test/algorithms/set_operations/difference/difference_areal_linear.cpp index 80e535130..046b8c800 100644 --- a/test/algorithms/set_operations/difference/difference_areal_linear.cpp +++ b/test/algorithms/set_operations/difference/difference_areal_linear.cpp @@ -3,9 +3,8 @@ // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015, 2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. - +// This file was modified by Oracle on 2015-2021. +// Modifications copyright (c) 2015-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 @@ -116,7 +115,7 @@ void test_areal_linear() test_one_lp("case26", "LINESTRING(4 0,4 3,4 5,7 5)", poly_9, 2, 5, 5.0); test_one_lp("case27", "LINESTRING(4 4,4 5,5 5)", poly_9, 1, 3, 2.0); - if (BOOST_GEOMETRY_CONDITION( (! boost::is_same::value)) ) + if (BOOST_GEOMETRY_CONDITION( (! std::is_same::value)) ) { // Fails for float test_one_lp("case28", diff --git a/test/algorithms/set_operations/difference/difference_tupled.cpp b/test/algorithms/set_operations/difference/difference_tupled.cpp index 30ecd2d50..631bb2d89 100644 --- a/test/algorithms/set_operations/difference/difference_tupled.cpp +++ b/test/algorithms/set_operations/difference/difference_tupled.cpp @@ -1,29 +1,25 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2020, Oracle and/or its affiliates. +// Copyright (c) 2020-2021, 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. // http://www.boost.org/users/license.html + #include +#include + +#include + #include #include #include #include #include -#include -#include -#include - -#include - -// TEMP -#include -#include -#include +#include typedef bg::model::point Pt; @@ -34,12 +30,6 @@ typedef bg::model::multi_point MPt; typedef bg::model::multi_linestring MLs; typedef bg::model::multi_polygon MPo; -#ifdef BOOST_GEOMETRY_CXX11_TUPLE - -#include - -#endif - template inline void check(std::string const& wkt1, std::string const& wkt2, @@ -83,8 +73,6 @@ inline void check(std::string const& wkt1, check(wkt1, wkt2, pair.second, out_str); } -#ifdef BOOST_GEOMETRY_CXX11_TUPLE - template inline void check(std::string const& wkt1, std::string const& wkt2, @@ -94,22 +82,13 @@ inline void check(std::string const& wkt1, check(wkt1, wkt2, std::get(tup), out_str); } -#endif - template -struct out_id - : boost::mpl::if_c - < - boost::is_base_of::type>::value, - boost::mpl::int_<0>, - typename boost::mpl::if_c - < - boost::is_base_of::type>::value, - boost::mpl::int_<1>, - boost::mpl::int_<2> - >::type - >::type -{}; +using out_id = std::integral_constant + < + int, + (bg::util::is_pointlike::value ? 0 : + (bg::util::is_linear::value ? 1 : 2)) + >; template inline void test_one(std::string const& in1_str, @@ -403,10 +382,7 @@ int test_main(int, char* []) { test_pair >(); test_tuple >(); - -#ifdef BOOST_GEOMETRY_CXX11_TUPLE test_tuple >(); -#endif return 0; } diff --git a/test/algorithms/set_operations/difference/test_difference.hpp b/test/algorithms/set_operations/difference/test_difference.hpp index 3c9ce08a5..c700d2957 100644 --- a/test/algorithms/set_operations/difference/test_difference.hpp +++ b/test/algorithms/set_operations/difference/test_difference.hpp @@ -25,7 +25,6 @@ #include "../setop_output_type.hpp" #include -#include #include #include diff --git a/test/algorithms/set_operations/intersection/intersection.cpp b/test/algorithms/set_operations/intersection/intersection.cpp index d2b93b7e2..7f3b4938e 100644 --- a/test/algorithms/set_operations/intersection/intersection.cpp +++ b/test/algorithms/set_operations/intersection/intersection.cpp @@ -5,8 +5,8 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015, 2016, 2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2021. +// Modifications copyright (c) 2015-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 @@ -941,9 +941,7 @@ int test_main(int, char* []) test_ticket_10868("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))"); } -#if defined(BOOST_HAS_LONG_LONG) - test_ticket_10868("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))"); -#endif + test_ticket_10868("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))"); #endif #endif diff --git a/test/algorithms/set_operations/intersection/test_intersection.hpp b/test/algorithms/set_operations/intersection/test_intersection.hpp index 12071d1b6..4583969ff 100644 --- a/test/algorithms/set_operations/intersection/test_intersection.hpp +++ b/test/algorithms/set_operations/intersection/test_intersection.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016-2020. -// Modifications copyright (c) 2016-2020, Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2021. +// Modifications copyright (c) 2016-2021, 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, @@ -17,7 +17,6 @@ #include #include -#include #include #include @@ -31,10 +30,9 @@ #include -#include - #include +#include #if defined(TEST_WITH_SVG) # include @@ -73,9 +71,7 @@ void check_result(IntersectionOutput const& intersection_output, typename bg::default_area_result::type length_or_area = 0; int n = 0; std::size_t nholes = 0; - for (typename IntersectionOutput::const_iterator it = intersection_output.begin(); - it != intersection_output.end(); - ++it) + for (auto it = intersection_output.begin(); it != intersection_output.end(); ++it) { if (! expected_count.empty()) { diff --git a/test/algorithms/set_operations/intersection/test_intersection_linear_linear.hpp b/test/algorithms/set_operations/intersection/test_intersection_linear_linear.hpp index 0b47c4f75..99c18ba96 100644 --- a/test/algorithms/set_operations/intersection/test_intersection_linear_linear.hpp +++ b/test/algorithms/set_operations/intersection/test_intersection_linear_linear.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2020, Oracle and/or its affiliates. +// 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 @@ -14,7 +14,6 @@ #include #include -#include #include #include "../test_set_ops_linear_linear.hpp" @@ -212,19 +211,8 @@ public: Geometry2 rg2(geometry2); bg::reverse(rg2); - typedef typename bg::tag_cast - < - Geometry1, bg::linear_tag - >::type tag1_type; - - typedef typename bg::tag_cast - < - Geometry2, bg::linear_tag - >::type tag2_type; - - bool const are_linear - = boost::is_same::value - && boost::is_same::value; + static const bool are_linear = bg::util::is_linear::value + && bg::util::is_linear::value; test_get_turns_ll_invariance::apply(geometry1, geometry2); #ifdef BOOST_GEOMETRY_TEST_DEBUG diff --git a/test/algorithms/set_operations/test_set_ops_linear_linear.hpp b/test/algorithms/set_operations/test_set_ops_linear_linear.hpp index d9bf57c2c..1692fca4d 100644 --- a/test/algorithms/set_operations/test_set_ops_linear_linear.hpp +++ b/test/algorithms/set_operations/test_set_ops_linear_linear.hpp @@ -1,7 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2020, Oracle and/or its affiliates. - +// 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 @@ -23,7 +22,6 @@ #include #include #include -#include #include #include @@ -35,14 +33,9 @@ namespace bg = ::boost::geometry; -template struct ls_less { - typedef typename boost::range_iterator::type Iterator1; - typedef typename boost::range_iterator::type Iterator2; - - typedef bg::less::type> point_less; - + template bool operator()(Linestring1 const& linestring1, Linestring2 const& linestring2) const { @@ -51,9 +44,10 @@ struct ls_less return boost::size(linestring1) < boost::size(linestring2); } - Iterator1 it1 = boost::begin(linestring1); - Iterator2 it2 = boost::begin(linestring2); - point_less less; + bg::less::type> less; + + auto it1 = boost::begin(linestring1); + auto it2 = boost::begin(linestring2); for (; it1 != boost::end(linestring1); ++it1, ++it2) { if (less(*it1, *it2)) @@ -70,21 +64,19 @@ struct ls_less }; -template struct ls_equal { + template bool operator()(Linestring1 const& linestring1, Linestring2 const& linestring2) const { - ls_less less; - + ls_less less; return ! less(linestring1, linestring2) && ! less(linestring2, linestring1); } }; -template class pt_equal { private: @@ -106,6 +98,7 @@ private: public: pt_equal(double tolerence) : m_tolerence(tolerence) {} + template bool operator()(Point1 const& point1, Point2 const& point2) const { // allow for some tolerence in testing equality of points @@ -121,11 +114,6 @@ struct multilinestring_equals template struct unique { - typedef typename boost::range_value::type Linestring; - typedef typename bg::point_type::type point_type; - typedef ls_equal linestring_equal; - typedef pt_equal point_equal; - template void apply_to_range(Range& range, EqualTo const& equal_to) { @@ -139,9 +127,9 @@ struct multilinestring_equals for (typename boost::range_iterator::type it = boost::begin(mls); it != boost::end(mls); ++it) { - apply_to_range(*it, point_equal(tolerance)); + apply_to_range(*it, pt_equal(tolerance)); } - apply_to_range(mls, linestring_equal()); + apply_to_range(mls, ls_equal()); } }; @@ -159,50 +147,11 @@ struct multilinestring_equals MultiLinestring2 const& multilinestring2, double tolerance) { - typedef typename boost::range_iterator - < - MultiLinestring1 const - >::type ls1_iterator; - - typedef typename boost::range_iterator - < - MultiLinestring2 const - >::type ls2_iterator; - - typedef typename boost::range_value::type Linestring1; - - typedef typename boost::range_value::type Linestring2; - - typedef typename boost::range_iterator - < - Linestring1 const - >::type point1_iterator; - - typedef typename boost::range_iterator - < - Linestring2 const - >::type point2_iterator; - - typedef ls_less linestring_less; - - typedef pt_equal - < - typename boost::range_value - < - typename boost::range_value::type - >::type, - typename boost::range_value - < - typename boost::range_value::type - >::type - > point_equal; - - MultiLinestring1 mls1 = multilinestring1; MultiLinestring2 mls2 = multilinestring2; - std::sort(boost::begin(mls1), boost::end(mls1), linestring_less()); - std::sort(boost::begin(mls2), boost::end(mls2), linestring_less()); + std::sort(boost::begin(mls1), boost::end(mls1), ls_less()); + std::sort(boost::begin(mls2), boost::end(mls2), ls_less()); unique()(mls1, tolerance); unique()(mls2, tolerance); @@ -212,19 +161,19 @@ struct multilinestring_equals return false; } - ls1_iterator it1 = boost::begin(mls1); - ls2_iterator it2 = boost::begin(mls2); + auto it1 = boost::begin(mls1); + auto it2 = boost::begin(mls2); for (; it1 != boost::end(mls1); ++it1, ++it2) { if (boost::size(*it1) != boost::size(*it2)) { return false; } - point1_iterator pit1 = boost::begin(*it1); - point2_iterator pit2 = boost::begin(*it2); + auto pit1 = boost::begin(*it1); + auto pit2 = boost::begin(*it2); for (; pit1 != boost::end(*it1); ++pit1, ++pit2) { - if (! point_equal(tolerance)(*pit1, *pit2)) + if (! pt_equal(tolerance)(*pit1, *pit2)) { return false; } @@ -257,9 +206,7 @@ private: convert_isolated_points_to_segments(MultiLinestring const& multilinestring, OutputIterator oit) { - BOOST_AUTO_TPL(it, boost::begin(multilinestring)); - - for (; it != boost::end(multilinestring); ++it) + for (auto it = boost::begin(multilinestring) ; it != boost::end(multilinestring); ++it) { if (boost::size(*it) == 1) { diff --git a/test/algorithms/set_operations/test_set_ops_pointlike.hpp b/test/algorithms/set_operations/test_set_ops_pointlike.hpp index 1cbe5de84..d9ac392ce 100644 --- a/test/algorithms/set_operations/test_set_ops_pointlike.hpp +++ b/test/algorithms/set_operations/test_set_ops_pointlike.hpp @@ -1,7 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2020, Oracle and/or its affiliates. - +// 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 @@ -12,30 +11,27 @@ #define BOOST_GEOMETRY_TEST_SET_OPS_POINTLIKE_HPP -#include - -namespace bg = ::boost::geometry; - #include #include #include #include + #include #include #include #include -#include - -#include -#include - -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include + +namespace bg = ::boost::geometry; //================================================================== @@ -69,8 +65,7 @@ void set_operation_output(std::string const& set_op_id, mapper.map(g2, "stroke-opacity:1;stroke:rgb(153,204,0);stroke-width:4"); mapper.map(g1, "stroke-opacity:1;stroke:rgb(51,51,153);stroke-width:2"); - BOOST_AUTO_TPL(it, output.begin()); - for (; it != output.end(); ++it) + for (auto it = output.begin(); it != output.end(); ++it) { mapper.map(*it, "fill:rgb(255,0,255);stroke:rgb(0,0,0);stroke-width:1", @@ -106,8 +101,8 @@ struct equals return false; } - BOOST_AUTO_TPL(it1, boost::begin(mp1)); - BOOST_AUTO_TPL(it2, boost::begin(mp2)); + auto it1 = boost::begin(mp1); + auto it2 = boost::begin(mp2); for (; it1 != boost::end(mp1); ++it1, ++it2) { if ( !bg::equals(*it1, *it2) ) diff --git a/test/algorithms/set_operations/union/test_union.hpp b/test/algorithms/set_operations/union/test_union.hpp index e17012265..55c468134 100644 --- a/test/algorithms/set_operations/union/test_union.hpp +++ b/test/algorithms/set_operations/union/test_union.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015-2020. -// Modifications copyright (c) 2015-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2021. +// Modifications copyright (c) 2015-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 @@ -24,7 +24,6 @@ #include "../setop_output_type.hpp" #include -#include #include #include #include @@ -41,15 +40,15 @@ #include -#include - #include - #if defined(TEST_WITH_SVG) # include #endif +#include + + struct ut_settings : public ut_base_settings { ut_settings() @@ -80,8 +79,7 @@ template inline std::size_t num_points(Range const& rng, bool add_for_open = false) { std::size_t result = 0; - for (typename boost::range_iterator::type it = boost::begin(rng); - it != boost::end(rng); ++it) + for (auto it = boost::begin(rng); it != boost::end(rng); ++it) { result += bg::num_points(*it, add_for_open); } @@ -139,8 +137,7 @@ void test_union(std::string const& caseid, G1 const& g1, G2 const& g2, typename bg::default_area_result::type area = 0; std::size_t n = 0; std::size_t holes = 0; - for (typename result_type::iterator it = clip.begin(); - it != clip.end(); ++it) + for (auto it = clip.begin(); it != clip.end(); ++it) { area += bg::area(*it); holes += bg::num_interior_rings(*it); @@ -158,9 +155,7 @@ void test_union(std::string const& caseid, G1 const& g1, G2 const& g2, typename bg::default_area_result::type area_inserted = 0; int index = 0; - for (typename result_type::iterator it = inserted.begin(); - it != inserted.end(); - ++it, ++index) + for (auto it = inserted.begin(); it != inserted.end(); ++it, ++index) { // Skip the empty polygon created above to avoid the empty_input_exception if (! bg::is_empty(*it)) diff --git a/test/algorithms/set_operations/union/union.cpp b/test/algorithms/set_operations/union/union.cpp index 31b7c6204..7daec1990 100644 --- a/test/algorithms/set_operations/union/union.cpp +++ b/test/algorithms/set_operations/union/union.cpp @@ -5,8 +5,8 @@ // Copyright (c) 2008-2016 Bruno Lalande, Paris, France. // Copyright (c) 2009-2016 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2016,2017. -// Modifications copyright (c) 2016-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2021. +// Modifications copyright (c) 2016-2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -45,7 +45,7 @@ void test_areal() typedef typename bg::coordinate_type::type ct; ut_settings ignore_validity_for_float; - if (BOOST_GEOMETRY_CONDITION((boost::is_same::value)) ) + if (BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { ignore_validity_for_float.set_test_validity(false); } diff --git a/test/algorithms/simplify_countries.cpp b/test/algorithms/simplify_countries.cpp index 87f674339..3b5dbb834 100644 --- a/test/algorithms/simplify_countries.cpp +++ b/test/algorithms/simplify_countries.cpp @@ -3,23 +3,32 @@ // Copyright (c) 2018 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include - -#include #include +#include + +#include +#include + +#include + +#include +#include + #if defined(TEST_WITH_SVG) # include #endif - template std::string read_from_file(std::string const& filename) { @@ -102,7 +111,7 @@ void test_one(std::string const& caseid, std::string const& wkt, mapper.map(geometry, "fill-opacity:0.5;fill:rgb(153,204,0);" "stroke:rgb(153,204,0);stroke-width:1"); - BOOST_FOREACH(polygon const& pol, simplified) + for (polygon const& pol : simplified) { mapper.map(pol, bg::area(pol) > 0 ? "fill:none;stroke:rgb(255,0,0);stroke-width:1" diff --git a/test/algorithms/transform.cpp b/test/algorithms/transform.cpp index bc938845d..9f88e0e89 100644 --- a/test/algorithms/transform.cpp +++ b/test/algorithms/transform.cpp @@ -5,6 +5,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -15,7 +19,6 @@ #include #include -#include #include #include @@ -71,10 +74,10 @@ void test_transform_linestring(Value value) boost::variant v(line1); line2_type expected; - for (BOOST_AUTO(p, line1.begin()); p != line1.end(); ++p) + for (auto it = line1.begin(); it != line1.end(); ++it) { P2 new_point; - bg::assign(new_point, *p); + bg::assign(new_point, *it); bg::multiply_value(new_point, value); expected.push_back(new_point); } diff --git a/test/algorithms/within/within_pointlike_geometry.cpp b/test/algorithms/within/within_pointlike_geometry.cpp index d04b0762d..84028ee90 100644 --- a/test/algorithms/within/within_pointlike_geometry.cpp +++ b/test/algorithms/within/within_pointlike_geometry.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2015, 2016, 2017. -// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014-2021. +// Modifications copyright (c) 2014-2021 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, @@ -154,19 +154,19 @@ void test_spherical_geographic() { bg::model::polygon wrangel; - typename boost::mpl::if_ + std::conditional_t < - boost::is_same::type, bg::geographic_tag>, + std::is_same::type, bg::geographic_tag>::value, bg::strategy::within::geographic_winding, bg::strategy::within::spherical_winding - >::type ws; + > ws; - typename boost::mpl::if_ + std::conditional_t < - boost::is_same::type, bg::geographic_tag>, + std::is_same::type, bg::geographic_tag>::value, bg::strategy::side::geographic<>, bg::strategy::side::spherical_side_formula<> - >::type ss; + > ss; boost::ignore_unused(ws, ss); @@ -390,8 +390,8 @@ void test_large_integers() void test_tickets() { - typedef boost::geometry::model::d2::point_xy pt; - typedef boost::geometry::model::ring ring; + typedef bg::model::d2::point_xy pt; + typedef bg::model::ring ring; // https://svn.boost.org/trac/boost/ticket/9628 { @@ -408,9 +408,9 @@ void test_tickets() pt p( -12260.669324773118, 54820.312032458634 ); - //boost::geometry::correct(r); + //bg::correct(r); - bool within = boost::geometry::within(p, r); + bool within = bg::within(p, r); BOOST_CHECK_EQUAL(within, false); } // similar @@ -423,7 +423,7 @@ void test_tickets() pt p( -13826.0, 54820.312032458634 ); - bool within = boost::geometry::within(p, r); + bool within = bg::within(p, r); BOOST_CHECK_EQUAL(within, false); } @@ -433,9 +433,9 @@ void test_tickets() ring r; bg::read_wkt("POINT(0.1377 5.00)", p); bg::read_wkt("POLYGON((0.1277 4.97, 0.1277 5.00, 0.1278 4.9999999999999982, 0.1278 4.97, 0.1277 4.97))", r); - bool within = boost::geometry::within(p, r); + bool within = bg::within(p, r); BOOST_CHECK_EQUAL(within, false); - bool covered_by = boost::geometry::covered_by(p, r); + bool covered_by = bg::covered_by(p, r); BOOST_CHECK_EQUAL(covered_by, false); } } diff --git a/test/core/point_type.cpp b/test/core/point_type.cpp index be98d2edb..6829450f2 100644 --- a/test/core/point_type.cpp +++ b/test/core/point_type.cpp @@ -5,7 +5,6 @@ // This file was modified by Oracle on 2014-2021. // Modifications copyright (c) 2014-2021 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, @@ -15,8 +14,6 @@ #include -#include - #include #include @@ -45,7 +42,7 @@ void test_geometry() BOOST_CHECK_EQUAL(typeid(typename bg::point_type::type).name(), typeid(Expected).name()); - static const bool is_same = boost::is_same::type, Expected>::value; + static const bool is_same = std::is_same::type, Expected>::value; BOOST_CHECK(is_same); } diff --git a/test/core/tag.cpp b/test/core/tag.cpp index f67c58d4b..36bf3403b 100644 --- a/test/core/tag.cpp +++ b/test/core/tag.cpp @@ -3,9 +3,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014 Oracle and/or its affiliates. - +// This file was modified by Oracle on 2014-2021. +// Modifications copyright (c) 2014-2021 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, @@ -15,8 +14,6 @@ #include -#include - #include #include @@ -42,7 +39,7 @@ void test_geometry() BOOST_CHECK_EQUAL(typeid(typename bg::tag::type).name(), typeid(Expected).name()); - static const bool is_same = boost::is_same::type, Expected>::value; + static const bool is_same = std::is_same::type, Expected>::value; BOOST_CHECK(is_same); } diff --git a/test/geometry_test_common.hpp b/test/geometry_test_common.hpp index 96866bde3..0c34e463a 100644 --- a/test/geometry_test_common.hpp +++ b/test/geometry_test_common.hpp @@ -4,6 +4,10 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -50,7 +54,6 @@ #include #include #include -#include #include @@ -171,14 +174,14 @@ using default_test_type = double; template inline T if_typed(T value_typed, T value) { - return boost::is_same::value ? value_typed : value; + return std::is_same::value ? value_typed : value; } //! Compile time function for expectations depending on high precision template inline T1 const& bg_if_mp(T1 const& value_mp, T2 const& value) { - return boost::is_same::type::value ? value_mp : value; + return std::is_same::type::value ? value_mp : value; } //! Macro for expectations depending on rescaling diff --git a/test/iterators/flatten_iterator.cpp b/test/iterators/flatten_iterator.cpp index 9f989594e..69acae554 100644 --- a/test/iterators/flatten_iterator.cpp +++ b/test/iterators/flatten_iterator.cpp @@ -1,9 +1,9 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2014, Oracle and/or its affiliates. - +// 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -14,26 +14,24 @@ #include +#include #include #include +#include +#include #include #include -#include -#include - +#include #include -#include -#include -#include -#include #include #include -#include +#include + +#include #include "test_iterator_common.hpp" -#include using namespace boost::assign; @@ -41,12 +39,12 @@ using namespace boost::assign; template struct access_begin { - typedef typename boost::mpl::if_ - < - typename boost::is_const::type, - typename InnerContainer::const_iterator, - typename InnerContainer::iterator - >::type return_type; + using return_type = std::conditional_t + < + std::is_const::value, + typename InnerContainer::const_iterator, + typename InnerContainer::iterator + >; static inline return_type apply(InnerContainer& inner) { @@ -58,12 +56,12 @@ struct access_begin template struct access_end { - typedef typename boost::mpl::if_ - < - typename boost::is_const::type, - typename InnerContainer::const_iterator, - typename InnerContainer::iterator - >::type return_type; + using return_type = std::conditional_t + < + std::is_const::value, + typename InnerContainer::const_iterator, + typename InnerContainer::iterator + >; static inline return_type apply(InnerContainer& inner) { diff --git a/test/iterators/point_iterator.cpp b/test/iterators/point_iterator.cpp index 346021420..80af60a94 100644 --- a/test/iterators/point_iterator.cpp +++ b/test/iterators/point_iterator.cpp @@ -3,8 +3,7 @@ // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// Copyright (c) 2014-2017, Oracle and/or its affiliates. - +// 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,9 +27,11 @@ #include #include #include -#include #include -#include + +#include +#include +#include #include @@ -39,31 +40,23 @@ #include #include -#include -#include -#include - -#include - -#include - #include #include #include #include +#include + #include +#include + #include #include -// At the end because of conflicts with Boost.QVM -#include - namespace bg = ::boost::geometry; -namespace ba = ::boost::assign; typedef bg::model::point point_type; typedef bg::model::point point_type_3d; @@ -100,7 +93,7 @@ template inline Geometry from_wkt(std::string const& wkt) { Geometry geometry; - boost::geometry::read_wkt(wkt, geometry); + bg::read_wkt(wkt, geometry); return geometry; } @@ -147,7 +140,7 @@ template < typename Geometry, bool Enable = true, - bool IsConst = boost::is_const::value + bool IsConst = std::is_const::value > struct test_iterator_concepts { @@ -456,7 +449,7 @@ struct test_point_iterator_of_geometry // testing dereferencing/assignment - bool const is_reference = boost::is_reference + bool const is_reference = std::is_reference < typename std::iterator_traits::reference >::value; @@ -535,7 +528,7 @@ BOOST_AUTO_TEST_CASE( test_linestring_point_iterator ) ); tester::apply(from_wkt("LINESTRING(3 3,4 4,5 5)"), - ba::tuple_list_of(3,3)(4,4)(5,5) + TMP{{3,3},{4,4},{5,5}} ); #ifdef BOOST_GEOMETRY_TEST_DEBUG @@ -568,15 +561,15 @@ BOOST_AUTO_TEST_CASE( test_polygon_point_iterator ) ); tester::apply(from_wkt

("POLYGON((1 1,9 1,9 9,1 9),(5 5,6 5,6 6,5 6))"), - ba::tuple_list_of(1,1)(9,1)(9,9)(1,9)(5,5)(6,5)(6,6)(5,6) + TMP{{1,1},{9,1},{9,9},{1,9},{5,5},{6,5},{6,6},{5,6}} ); tester::apply(from_wkt

("POLYGON((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),())"), - ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9) + TMP{{3,3},{4,4},{5,5},{6,6},{7,7},{8,8},{9,9}} ); tester::apply(from_wkt

("POLYGON((),(3 3,4 4,5 5),(),(),(6 6,7 7,8 8),(),(),(9 9),())"), - ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9) + TMP{{3,3},{4,4},{5,5},{6,6},{7,7},{8,8},{9,9}} ); #ifdef BOOST_GEOMETRY_TEST_DEBUG @@ -605,7 +598,7 @@ BOOST_AUTO_TEST_CASE( test_multipoint_point_iterator ) ); tester::apply(from_wkt("MULTIPOINT(3 3,4 4,5 5)"), - ba::tuple_list_of(3,3)(4,4)(5,5) + TMP{{3,3},{4,4},{5,5}} ); #ifdef BOOST_GEOMETRY_TEST_DEBUG @@ -634,7 +627,7 @@ BOOST_AUTO_TEST_CASE( test_multipoint_3d_point_iterator ) ); tester::apply(from_wkt("MULTIPOINT(3 3 3,4 4 4,5 5 5)"), - ba::tuple_list_of(3,3,3)(4,4,4)(5,5,5) + TMP{{3,3,3},{4,4,4},{5,5,5}} ); #ifdef BOOST_GEOMETRY_TEST_DEBUG @@ -671,11 +664,11 @@ BOOST_AUTO_TEST_CASE( test_multilinestring_point_iterator ) ); tester::apply(from_wkt("MULTILINESTRING((1 1,2 2,3 3),(3 3,4 4,5 5),(6 6))"), - ba::tuple_list_of(1,1)(2,2)(3,3)(3,3)(4,4)(5,5)(6,6) + TMP{{1,1},{2,2},{3,3},{3,3},{4,4},{5,5},{6,6}} ); tester::apply(from_wkt("MULTILINESTRING((),(),(1 1,2 2,3 3),(),(),(3 3,4 4,5 5),(),(6 6),(),(),())"), - ba::tuple_list_of(1,1)(2,2)(3,3)(3,3)(4,4)(5,5)(6,6) + TMP{{1,1},{2,2},{3,3},{3,3},{4,4},{5,5},{6,6}} ); #ifdef BOOST_GEOMETRY_TEST_DEBUG @@ -716,18 +709,18 @@ BOOST_AUTO_TEST_CASE( test_multipolygon_point_iterator ) ); tester::apply(from_wkt("MULTIPOLYGON(((3 3,4 4,5 5),(6 6,7 7,8 8),(9 9)),((1 1,2 2,10 10),(11 11,12 12)))"), - ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\ - (1,1)(2,2)(10,10)(11,11)(12,12) + TMP{{3,3},{4,4},{5,5},{6,6},{7,7},{8,8},{9,9}, + {1,1},{2,2},{10,10},{11,11},{12,12}} ); tester::apply(from_wkt("MULTIPOLYGON(((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),()),((),(1 1,2 2,10 10),(),(),(),(11 11,12 12),(),(),(13 13),()))"), - ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\ - (1,1)(2,2)(10,10)(11,11)(12,12)(13,13) + TMP{{3,3},{4,4},{5,5},{6,6},{7,7},{8,8},{9,9}, + {1,1},{2,2},{10,10},{11,11},{12,12},{13,13}} ); tester::apply(from_wkt("MULTIPOLYGON(((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),()),((),(1 1,2 2,10 10),(),(),(),(11 11,12 12),(),(),(13 13),()),((),(),()))"), - ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\ - (1,1)(2,2)(10,10)(11,11)(12,12)(13,13) + TMP{{3,3},{4,4},{5,5},{6,6},{7,7},{8,8},{9,9}, + {1,1},{2,2},{10,10},{11,11},{12,12},{13,13}} ); #ifdef BOOST_GEOMETRY_TEST_DEBUG @@ -765,8 +758,8 @@ BOOST_AUTO_TEST_CASE( test_multipoint_of_point_pointers ) typedef test_point_iterator_of_geometry tester; tester::apply(multipoint, - ba::tuple_list_of(1,-1)(2,-2)(3,-3)(4,-4)(5,-5)(6,-6)\ - (7,-7)(8,-8)(9,-9), + TMP{{1,-1},{2,-2},{3,-3},{4,-4},{5,-5},{6,-6}, + {7,-7},{8,-8},{9,-9}}, zero ); @@ -807,8 +800,8 @@ BOOST_AUTO_TEST_CASE( test_linestring_of_point_pointers ) typedef test_point_iterator_of_geometry tester; tester::apply(linestring, - ba::tuple_list_of(1,-1)(2,-2)(3,-3)(4,-4)(5,-5)(6,-6)\ - (7,-7)(8,-8)(9,-9), + TMP{{1,-1},{2,-2},{3,-3},{4,-4},{5,-5},{6,-6}, + {7,-7},{8,-8},{9,-9}}, zero ); @@ -849,8 +842,8 @@ BOOST_AUTO_TEST_CASE( test_multipoint_copy_on_dereference ) tester::apply(multipoint, // from_wkt("MULTIPOINT(1 -1,2 -2,3 -3,4 -4,5 -5,6 -6, 7 -7,8 -8,9 -9)"), - ba::tuple_list_of(1,-1)(2,-2)(3,-3)(4,-4)(5,-5)(6,-6)\ - (7,-7)(8,-8)(9,-9) + TMP{{1,-1},{2,-2},{3,-3},{4,-4},{5,-5},{6,-6}, + {7,-7},{8,-8},{9,-9}} ); } @@ -875,7 +868,7 @@ BOOST_AUTO_TEST_CASE( test_linestring_copy_on_dereference ) > tester; tester::apply(from_wkt("LINESTRING(1 -1,2 -2,3 -3,4 -4,5 -5,6 -6, 7 -7,8 -8,9 -9)"), - ba::tuple_list_of(1,-1)(2,-2)(3,-3)(4,-4)(5,-5)(6,-6)\ - (7,-7)(8,-8)(9,-9) + TMP{{1,-1},{2,-2},{3,-3},{4,-4},{5,-5},{6,-6}, + {7,-7},{8,-8},{9,-9}} ); } diff --git a/test/iterators/segment_iterator.cpp b/test/iterators/segment_iterator.cpp index fdfe90ef5..53bd5ce63 100644 --- a/test/iterators/segment_iterator.cpp +++ b/test/iterators/segment_iterator.cpp @@ -3,9 +3,9 @@ // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// Copyright (c) 2014, Oracle and/or its affiliates. - +// 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -23,12 +23,17 @@ #include -#include #include #include #include #include +#include +#include +#include + +#include + #include #include #include @@ -37,25 +42,13 @@ #include #include -#include - -#include -#include -#include - -#include - #include -// TEMP -#include -#include -#include +#include #include #include -namespace ba = ::boost::assign; namespace bg = ::boost::geometry; namespace bgm = bg::model; @@ -87,7 +80,7 @@ template inline Geometry from_wkt(std::string const& wkt) { Geometry geometry; - boost::geometry::read_wkt(wkt, geometry); + bg::read_wkt(wkt, geometry); return geometry; } @@ -325,22 +318,23 @@ BOOST_AUTO_TEST_CASE( test_linestring_segment_iterator ) typedef test_segment_iterator_of_geometry tester; tester::apply(from_wkt("LINESTRING(0 0,1 1,2 2,3 3,4 4)"), - ba::list_of - ( ba::tuple_list_of(0,0)(1,1) ) - ( ba::tuple_list_of(1,1)(2,2) ) - ( ba::tuple_list_of(2,2)(3,3) ) - ( ba::tuple_list_of(3,3)(4,4) ) - ); + TML{ + {{0,0},{1,1}}, + {{1,1},{2,2}}, + {{2,2},{3,3}}, + {{3,3},{4,4}} + }); // linestring with no points tester::apply(from_wkt("LINESTRING()"), - ba::list_of() + TML() ); // linestring with a single point tester::apply(from_wkt("LINESTRING(1 0)"), - ba::list_of - ( ba::tuple_list_of(1,0)(1,0) ), + TML{ + {{1,0},{1,0}} + }, false ); @@ -365,80 +359,82 @@ BOOST_AUTO_TEST_CASE( test_ring_segment_iterator ) typedef dual_tester tester; tester::apply(from_wkt("POLYGON((0 0,0 10,10 10,10 0))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(10,10) ) - ( ba::tuple_list_of(10,10)(10,0) ) - ( ba::tuple_list_of(10,0)(0,0) ) - ); + TML{ + {{0,0},{0,10}}, + {{0,10},{10,10}}, + {{10,10},{10,0}}, + {{10,0},{0,0}} + }); // open ring with no points tester::apply(from_wkt("POLYGON(())"), - ba::list_of() + TML() ); // open ring with a single point (one segment) tester::apply(from_wkt("POLYGON((0 0))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,0) ), + TML{ + {{0,0},{0,0}} + }, false ); // open ring with a two points (two segments) tester::apply(from_wkt("POLYGON((0 0,0 10))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(0,0) ) - ); + TML{ + {{0,0},{0,10}}, + {{0,10},{0,0}} + }); // open ring with a three points (three segments) tester::apply(from_wkt("POLYGON((0 0,0 10,10 10))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(10,10) ) - ( ba::tuple_list_of(10,10)(0,0) ) - ); + TML{ + {{0,0},{0,10}}, + {{0,10},{10,10}}, + {{10,10},{0,0}} + }); tester::apply(from_wkt("POLYGON((0 0,0 10,10 10,10 0,0 0))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(10,10) ) - ( ba::tuple_list_of(10,10)(10,0) ) - ( ba::tuple_list_of(10,0)(0,0) ) - ); + TML{ + {{0,0},{0,10}}, + {{0,10},{10,10}}, + {{10,10},{10,0}}, + {{10,0},{0,0}} + }); // closed ring with no points tester::apply(from_wkt("POLYGON(())"), - ba::list_of() + TML() ); // closed ring with a single point (one segment) tester::apply(from_wkt("POLYGON((0 0))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,0) ), + TML{ + {{0,0},{0,0}} + }, false ); // closed ring with two points (one segment) tester::apply(from_wkt("POLYGON((0 0,0 0))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,0) ) - ); + TML{ + {{0,0},{0,0}} + }); // closed ring with three points (two segments) tester::apply(from_wkt("POLYGON((0 0,0 10,0 0))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(0,0) ) - ); + TML{ + {{0,0},{0,10}}, + {{0,10},{0,0}} + }); // closed ring with four points (three segments) tester::apply(from_wkt("POLYGON((0 0,0 10,10 10,0 0))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(10,10) ) - ( ba::tuple_list_of(10,10)(0,0) ) - ); + TML{ + {{0,0},{0,10}}, + {{0,10},{10,10}}, + {{10,10},{0,0}} + }); #ifdef BOOST_GEOMETRY_TEST_DEBUG std::cout << std::endl << std::endl << std::endl; @@ -461,85 +457,89 @@ BOOST_AUTO_TEST_CASE( test_polygon_segment_iterator ) typedef dual_tester tester; tester::apply(from_wkt("POLYGON((0 0,0 10,10 10,10 0),(1 1,9 1,9 9,1 9))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(10,10) ) - ( ba::tuple_list_of(10,10)(10,0) ) - ( ba::tuple_list_of(10,0)(0,0) ) - ( ba::tuple_list_of(1,1)(9,1) ) - ( ba::tuple_list_of(9,1)(9,9) ) - ( ba::tuple_list_of(9,9)(1,9) ) - ( ba::tuple_list_of(1,9)(1,1) ) - ); + TML{ + {{0,0},{0,10}}, + {{0,10},{10,10}}, + {{10,10},{10,0}}, + {{10,0},{0,0}}, + {{1,1},{9,1}}, + {{9,1},{9,9}}, + {{9,9},{1,9}}, + {{1,9},{1,1}} + }); // open polygon with no points tester::apply(from_wkt("POLYGON(())"), - ba::list_of() + TML() ); // open polygons with single-point rings tester::apply(from_wkt("POLYGON((0 0,0 10,10 10,10 0),(1 1))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(10,10) ) - ( ba::tuple_list_of(10,10)(10,0) ) - ( ba::tuple_list_of(10,0)(0,0) ) - ( ba::tuple_list_of(1,1)(1,1) ), + TML{ + {{0,0},{0,10}}, + {{0,10},{10,10}}, + {{10,10},{10,0}}, + {{10,0},{0,0}}, + {{1,1},{1,1}} + }, false ); tester::apply(from_wkt("POLYGON((0 0),(1 1,9 1,9 9,1 9))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,0) ) - ( ba::tuple_list_of(1,1)(9,1) ) - ( ba::tuple_list_of(9,1)(9,9) ) - ( ba::tuple_list_of(9,9)(1,9) ) - ( ba::tuple_list_of(1,9)(1,1) ), + TML{ + {{0,0},{0,0}}, + {{1,1},{9,1}}, + {{9,1},{9,9}}, + {{9,9},{1,9}}, + {{1,9},{1,1}} + }, false ); tester::apply(from_wkt("POLYGON((0 0,0 10,10 10,10 0,0 0),(1 1,9 1,9 9,1 9,1 1))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(10,10) ) - ( ba::tuple_list_of(10,10)(10,0) ) - ( ba::tuple_list_of(10,0)(0,0) ) - ( ba::tuple_list_of(1,1)(9,1) ) - ( ba::tuple_list_of(9,1)(9,9) ) - ( ba::tuple_list_of(9,9)(1,9) ) - ( ba::tuple_list_of(1,9)(1,1) ) - ); + TML{ + {{0,0},{0,10}}, + {{0,10},{10,10}}, + {{10,10},{10,0}}, + {{10,0},{0,0}}, + {{1,1},{9,1}}, + {{9,1},{9,9}}, + {{9,9},{1,9}}, + {{1,9},{1,1}} + }); // closed polygons with no points tester::apply(from_wkt("POLYGON(())"), - ba::list_of() + TML() ); tester::apply(from_wkt("POLYGON((),())"), - ba::list_of() + TML() ); tester::apply(from_wkt("POLYGON((),(),())"), - ba::list_of() + TML() ); // closed polygons with single-point rings tester::apply(from_wkt("POLYGON((0 0,0 10,10 10,10 0,0 0),(1 1))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(10,10) ) - ( ba::tuple_list_of(10,10)(10,0) ) - ( ba::tuple_list_of(10,0)(0,0) ) - ( ba::tuple_list_of(1,1)(1,1) ), + TML{ + {{0,0},{0,10}}, + {{0,10},{10,10}}, + {{10,10},{10,0}}, + {{10,0},{0,0}}, + {{1,1},{1,1}}, + }, false ); tester::apply(from_wkt("POLYGON((0 0),(1 1,9 1,9 9,1 9,1 1))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,0) ) - ( ba::tuple_list_of(1,1)(9,1) ) - ( ba::tuple_list_of(9,1)(9,9) ) - ( ba::tuple_list_of(9,9)(1,9) ) - ( ba::tuple_list_of(1,9)(1,1) ), + TML{ + {{0,0},{0,0}}, + {{1,1},{9,1}}, + {{9,1},{9,9}}, + {{9,9},{1,9}}, + {{1,9},{1,1}} + }, false ); @@ -563,37 +563,38 @@ BOOST_AUTO_TEST_CASE( test_multi_linestring_segment_iterator ) typedef test_segment_iterator_of_geometry tester; tester::apply(from_wkt("MULTILINESTRING((0 0,1 1,2 2,3 3,4 4),(5 5,6 6,7 7,8 8),(9 9,10 10))"), - ba::list_of - ( ba::tuple_list_of(0,0)(1,1) ) - ( ba::tuple_list_of(1,1)(2,2) ) - ( ba::tuple_list_of(2,2)(3,3) ) - ( ba::tuple_list_of(3,3)(4,4) ) - ( ba::tuple_list_of(5,5)(6,6) ) - ( ba::tuple_list_of(6,6)(7,7) ) - ( ba::tuple_list_of(7,7)(8,8) ) - ( ba::tuple_list_of(9,9)(10,10) ) - ); + TML{ + {{0,0},{1,1}}, + {{1,1},{2,2}}, + {{2,2},{3,3}}, + {{3,3},{4,4}}, + {{5,5},{6,6}}, + {{6,6},{7,7}}, + {{7,7},{8,8}}, + {{9,9},{10,10}} + }); // empty multi-linestrings tester::apply(from_wkt("MULTILINESTRING()"), - ba::list_of() + TML() ); tester::apply(from_wkt("MULTILINESTRING(())"), - ba::list_of() + TML() ); tester::apply(from_wkt("MULTILINESTRING((),())"), - ba::list_of() + TML() ); // multi-linestring with a linestring with one point tester::apply(from_wkt("MULTILINESTRING((0 0,1 1,2 2,3 3,4 4),(5 5),(9 9,10 10))"), - ba::list_of - ( ba::tuple_list_of(0,0)(1,1) ) - ( ba::tuple_list_of(1,1)(2,2) ) - ( ba::tuple_list_of(2,2)(3,3) ) - ( ba::tuple_list_of(3,3)(4,4) ) - ( ba::tuple_list_of(5,5)(5,5) ) - ( ba::tuple_list_of(9,9)(10,10) ), + TML{ + {{0,0},{1,1}}, + {{1,1},{2,2}}, + {{2,2},{3,3}}, + {{3,3},{4,4}}, + {{5,5},{5,5}}, + {{9,9},{10,10}} + }, false ); @@ -618,63 +619,63 @@ BOOST_AUTO_TEST_CASE( test_multi_polygon_segment_iterator ) typedef dual_tester tester; tester::apply(from_wkt("MULTIPOLYGON(((0 0,0 10,10 10,10 0),(1 1,9 1,9 9,1 9)),((20 0,20 10,30 10,30 0),(21 1,29 1,29 9,21 9)))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(10,10) ) - ( ba::tuple_list_of(10,10)(10,0) ) - ( ba::tuple_list_of(10,0)(0,0) ) - ( ba::tuple_list_of(1,1)(9,1) ) - ( ba::tuple_list_of(9,1)(9,9) ) - ( ba::tuple_list_of(9,9)(1,9) ) - ( ba::tuple_list_of(1,9)(1,1) ) - ( ba::tuple_list_of(20,0)(20,10) ) - ( ba::tuple_list_of(20,10)(30,10) ) - ( ba::tuple_list_of(30,10)(30,0) ) - ( ba::tuple_list_of(30,0)(20,0) ) - ( ba::tuple_list_of(21,1)(29,1) ) - ( ba::tuple_list_of(29,1)(29,9) ) - ( ba::tuple_list_of(29,9)(21,9) ) - ( ba::tuple_list_of(21,9)(21,1) ) - ); + TML{ + {{0,0},{0,10}}, + {{0,10},{10,10}}, + {{10,10},{10,0}}, + {{10,0},{0,0}}, + {{1,1},{9,1}}, + {{9,1},{9,9}}, + {{9,9},{1,9}}, + {{1,9},{1,1}}, + {{20,0},{20,10}}, + {{20,10},{30,10}}, + {{30,10},{30,0}}, + {{30,0},{20,0}}, + {{21,1},{29,1}}, + {{29,1},{29,9}}, + {{29,9},{21,9}}, + {{21,9},{21,1}} + }); tester::apply(from_wkt("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0),(1 1,9 1,9 9,1 9,1 1)),((20 0,20 10,30 10,30 0,20 0),(21 1,29 1,29 9,21 9,21 1)))"), - ba::list_of - ( ba::tuple_list_of(0,0)(0,10) ) - ( ba::tuple_list_of(0,10)(10,10) ) - ( ba::tuple_list_of(10,10)(10,0) ) - ( ba::tuple_list_of(10,0)(0,0) ) - ( ba::tuple_list_of(1,1)(9,1) ) - ( ba::tuple_list_of(9,1)(9,9) ) - ( ba::tuple_list_of(9,9)(1,9) ) - ( ba::tuple_list_of(1,9)(1,1) ) - ( ba::tuple_list_of(20,0)(20,10) ) - ( ba::tuple_list_of(20,10)(30,10) ) - ( ba::tuple_list_of(30,10)(30,0) ) - ( ba::tuple_list_of(30,0)(20,0) ) - ( ba::tuple_list_of(21,1)(29,1) ) - ( ba::tuple_list_of(29,1)(29,9) ) - ( ba::tuple_list_of(29,9)(21,9) ) - ( ba::tuple_list_of(21,9)(21,1) ) - ); + TML{ + {{0,0},{0,10}}, + {{0,10},{10,10}}, + {{10,10},{10,0}}, + {{10,0},{0,0}}, + {{1,1},{9,1}}, + {{9,1},{9,9}}, + {{9,9},{1,9}}, + {{1,9},{1,1}}, + {{20,0},{20,10}}, + {{20,10},{30,10}}, + {{30,10},{30,0}}, + {{30,0},{20,0}}, + {{21,1},{29,1}}, + {{29,1},{29,9}}, + {{29,9},{21,9}}, + {{21,9},{21,1}} + }); // test empty closed multi-polygons tester::apply(from_wkt("MULTIPOLYGON()"), - ba::list_of() + TML() ); tester::apply(from_wkt("MULTIPOLYGON((()))"), - ba::list_of() + TML() ); tester::apply(from_wkt("MULTIPOLYGON(((),()))"), - ba::list_of() + TML() ); tester::apply(from_wkt("MULTIPOLYGON(((),(),()))"), - ba::list_of() + TML() ); tester::apply(from_wkt("MULTIPOLYGON(((),(),()),(()))"), - ba::list_of() + TML() ); tester::apply(from_wkt("MULTIPOLYGON(((),(),()),((),()))"), - ba::list_of() + TML() ); #ifdef BOOST_GEOMETRY_TEST_DEBUG @@ -711,16 +712,16 @@ BOOST_AUTO_TEST_CASE( test_linestring_of_point_pointers ) typedef test_segment_iterator_of_geometry tester; tester::apply(linestring, - ba::list_of - ( ba::tuple_list_of(1,-1)(2,-2) ) - ( ba::tuple_list_of(2,-2)(3,-3) ) - ( ba::tuple_list_of(3,-3)(4,-4) ) - ( ba::tuple_list_of(4,-4)(5,-5) ) - ( ba::tuple_list_of(5,-5)(6,-6) ) - ( ba::tuple_list_of(6,-6)(7,-7) ) - ( ba::tuple_list_of(7,-7)(8,-8) ) - ( ba::tuple_list_of(8,-8)(9,-9) ) - ); + TML{ + {{1,-1},{2,-2}}, + {{2,-2},{3,-3}}, + {{3,-3},{4,-4}}, + {{4,-4},{5,-5}}, + {{5,-5},{6,-6}}, + {{6,-6},{7,-7}}, + {{7,-7},{8,-8}}, + {{8,-8},{9,-9}} + }); for (unsigned int i = 0; i < linestring.size(); i++) { @@ -744,14 +745,14 @@ BOOST_AUTO_TEST_CASE( test_linestring_copy_on_dereference ) typedef test_segment_iterator_of_geometry tester; tester::apply(from_wkt("LINESTRING(1 -1,2 -2,3 -3,4 -4,5 -5,6 -6, 7 -7,8 -8,9 -9)"), - ba::list_of - ( ba::tuple_list_of(1,-1)(2,-2) ) - ( ba::tuple_list_of(2,-2)(3,-3) ) - ( ba::tuple_list_of(3,-3)(4,-4) ) - ( ba::tuple_list_of(4,-4)(5,-5) ) - ( ba::tuple_list_of(5,-5)(6,-6) ) - ( ba::tuple_list_of(6,-6)(7,-7) ) - ( ba::tuple_list_of(7,-7)(8,-8) ) - ( ba::tuple_list_of(8,-8)(9,-9) ) - ); + TML{ + {{1,-1},{2,-2}}, + {{2,-2},{3,-3}}, + {{3,-3},{4,-4}}, + {{4,-4},{5,-5}}, + {{5,-5},{6,-6}}, + {{6,-6},{7,-7}}, + {{7,-7},{8,-8}}, + {{8,-8},{9,-9}} + }); } diff --git a/test/policies/rescale_policy.cpp b/test/policies/rescale_policy.cpp index c91f31988..f86b95bd7 100644 --- a/test/policies/rescale_policy.cpp +++ b/test/policies/rescale_policy.cpp @@ -5,6 +5,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -15,21 +19,15 @@ #include #include -#include - #include #include #include #include -#include -#include -#include -#include -#include - #include - - +#include +#include +#include +#include #include @@ -94,14 +92,14 @@ static std::string simplex_large[2] = template void test_rescale(std::string const& expected_normal, std::string const& expected_large) { - typedef bg::model::polygon

polygon; + using polygon = bg::model::polygon

; - typedef typename boost::mpl::if_c + using rescale_policy_type = std::conditional_t < Rescale, - typename bg::rescale_policy_type

::type , + typename bg::rescale_policy_type

::type, bg::detail::no_rescale_policy - >::type rescale_policy_type; + >; test_one( simplex_normal[0], simplex_normal[1], @@ -125,7 +123,7 @@ int test_main(int, char* []) test_all("-5000000 -3000000", "-5000000 -3000000"); test_all("-5000000 -3000000", "-5000000 -3000000"); test_all("0 1", "0 1000"); - test_all("0 1", "0 1000"); + test_all("0 1", "0 1000"); // test_all(); // compiles but overflows return 0; diff --git a/test/robustness/overlay/areal_areal/general_intersection_precision.cpp b/test/robustness/overlay/areal_areal/general_intersection_precision.cpp index 6413f2d18..afd1bdbac 100644 --- a/test/robustness/overlay/areal_areal/general_intersection_precision.cpp +++ b/test/robustness/overlay/areal_areal/general_intersection_precision.cpp @@ -3,6 +3,10 @@ // Copyright (c) 2019 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -13,8 +17,6 @@ #include #include -#include - #include #include diff --git a/test/robustness/overlay/areal_areal/test_overlay_p_q.hpp b/test/robustness/overlay/areal_areal/test_overlay_p_q.hpp index 57813450f..2e1f421ce 100644 --- a/test/robustness/overlay/areal_areal/test_overlay_p_q.hpp +++ b/test/robustness/overlay/areal_areal/test_overlay_p_q.hpp @@ -1,7 +1,12 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Robustness Test -// + // Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -14,8 +19,6 @@ #include #include -#include - #include // For mixing int/float @@ -274,12 +277,12 @@ static bool test_overlay_p_q(std::string const& caseid, if (settings.also_difference) { - for (BOOST_AUTO(it, out_d1.begin()); it != out_d1.end(); ++it) + for (auto it = out_d1.begin(); it != out_d1.end(); ++it) { mapper.map(*it, "opacity:0.8;fill:none;stroke:rgb(255,128,0);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round"); } - for (BOOST_AUTO(it, out_d2.begin()); it != out_d2.end(); ++it) + for (auto it = out_d2.begin(); it != out_d2.end(); ++it) { mapper.map(*it, "opacity:0.8;fill:none;stroke:rgb(255,0,255);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round"); diff --git a/test/robustness/overlay/areal_areal/ticket_9081.cpp b/test/robustness/overlay/areal_areal/ticket_9081.cpp index 91f336c6f..6de0d1ce6 100644 --- a/test/robustness/overlay/areal_areal/ticket_9081.cpp +++ b/test/robustness/overlay/areal_areal/ticket_9081.cpp @@ -2,6 +2,10 @@ // Copyright (c) 2013-2015 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,23 +15,30 @@ #define CHECK_SELF_INTERSECTIONS #define LIST_WKT - #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 +#include +#include +#include + +#include +#include + +namespace bg = boost::geometry; typedef boost::geometry::model::d2::point_xy pt; typedef boost::geometry::model::polygon polygon; @@ -62,7 +73,7 @@ inline void debug_with_svg(int index, char method, Geometry const& a, Geometry c mapper.map(a, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2"); mapper.map(b, "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2"); - BOOST_FOREACH(polygon const& g, output) + for(polygon const& g : output) { mapper.map(g, "opacity:0.8;fill:none;stroke:rgb(255,128,0);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round"); } @@ -87,6 +98,14 @@ int main() std::string wkt1, wkt2, operation; + + typename bg::strategies::relate::services::default_strategy + < + multi_polygon, multi_polygon + >::type strategy; + + using rescale_policy_type = typename bg::rescale_policy_type::type; + try { @@ -94,19 +113,23 @@ int main() boost::timer t; std::vector poly_list; - for(int i=0;i(mp, strategy); + + bg::detail::overlay::has_self_intersections(mp, strategy, robust_policy); std::ostringstream out; out << "original " << poly_list.size(); @@ -119,7 +142,7 @@ int main() } - for(int j=0;j(mp_i, strategy); + try { - boost::geometry::detail::overlay::has_self_intersections(mp_i); + boost::geometry::detail::overlay::has_self_intersections(mp_i, strategy, robust_policy_i); } catch(...) { @@ -162,7 +189,7 @@ int main() std::cout << boost::geometry::wkt(mp_i) << std::endl; try { - boost::geometry::detail::overlay::has_self_intersections(mp_i); + boost::geometry::detail::overlay::has_self_intersections(mp_i, strategy, robust_policy_i); } catch(...) { @@ -170,9 +197,12 @@ int main() break; } + rescale_policy_type robust_policy_d + = bg::get_rescale_policy(mp_d, strategy); + try { - boost::geometry::detail::overlay::has_self_intersections(mp_d); + boost::geometry::detail::overlay::has_self_intersections(mp_d, strategy, robust_policy_d); } catch(...) { @@ -182,9 +212,13 @@ int main() std::cout << boost::geometry::wkt(mp_d) << std::endl; break; } + + rescale_policy_type robust_policy_e + = bg::get_rescale_policy(mp_e, strategy); + try { - boost::geometry::detail::overlay::has_self_intersections(mp_e); + boost::geometry::detail::overlay::has_self_intersections(mp_e, strategy, robust_policy_e); } catch(...) { diff --git a/test/robustness/overlay/buffer/multi_point_growth.cpp b/test/robustness/overlay/buffer/multi_point_growth.cpp index 4aed939cf..5058346eb 100644 --- a/test/robustness/overlay/buffer/multi_point_growth.cpp +++ b/test/robustness/overlay/buffer/multi_point_growth.cpp @@ -3,16 +3,24 @@ // Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include - -#include -#include +#include #include +#include + +#include + +#include +#include +#include +#include namespace bg = boost::geometry; @@ -73,7 +81,7 @@ double test_growth(Geometry const& geometry, int n, int d, double distance) typename bg::default_area_result::type area = 0; - BOOST_FOREACH(GeometryOut const& polygon, buffered) + for (GeometryOut const& polygon : buffered) { area += bg::area(polygon); } @@ -82,7 +90,7 @@ double test_growth(Geometry const& geometry, int n, int d, double distance) // Map input geometry in green mapper.map(geometry, "opacity:0.5;fill:rgb(0,128,0);stroke:rgb(0,128,0);stroke-width:10"); - BOOST_FOREACH(GeometryOut const& polygon, buffered) + for (GeometryOut const& polygon : buffered) { mapper.map(polygon, "opacity:0.4;fill:rgb(255,255,128);stroke:rgb(0,0,0);stroke-width:3"); } diff --git a/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp b/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp index 3fe64a3bc..13dba836b 100644 --- a/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp +++ b/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp @@ -3,10 +3,10 @@ // Copyright (c) 2012-2020 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015 Oracle and/or its affiliates. - +// This file was modified by Oracle on 2015-2021. +// Modifications copyright (c) 2015-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 // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -39,8 +39,8 @@ #include #include -#include -#include +#include +#include struct buffer_settings : public common_settings diff --git a/test/robustness/overlay/linear_areal/recursive_polygons_linear_areal.cpp b/test/robustness/overlay/linear_areal/recursive_polygons_linear_areal.cpp index b3a5311b4..adb6a65ac 100644 --- a/test/robustness/overlay/linear_areal/recursive_polygons_linear_areal.cpp +++ b/test/robustness/overlay/linear_areal/recursive_polygons_linear_areal.cpp @@ -3,6 +3,10 @@ // Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -15,7 +19,6 @@ #include #include -#include #include #include #include @@ -23,15 +26,21 @@ #include #include -#include +#include +#include +#include +#include +#include + +#include + #include #include #include -#include -#include -#include +#include +#include namespace bg = boost::geometry; @@ -197,20 +206,18 @@ public : typedef typename bg::point_type::type pt; typedef bg::model::segment segment_type; - typedef bg::strategy::intersection::relate_cartesian_segments - < - bg::policies::relate::segments_intersection_points - < - segment_type, - segment_type, - bg::segment_intersection_points - > - > policy; + bg::strategy::intersection::cartesian_segments<> strategy; + bg::policies::relate::segments_intersection_points + < + bg::segment_intersection_points + > policy; segment_type seg1, seg2; bg::convert(m_segment, seg1); bg::convert(segment, seg2); - bg::segment_intersection_points is = policy::apply(seg1, seg2); + + // TODO: this function requires unique subranges now + bg::segment_intersection_points is = strategy.apply(seg1, seg2); if (is.count == 2) { @@ -297,7 +304,7 @@ bool verify(std::string const& caseid, MultiPolygon const& mp, Linestring const& bg::for_each_segment(difference, bc); // 3) check also the mid-points from the difference to remove false positives - BOOST_FOREACH(Linestring const& d, difference) + for (Linestring const& d : difference) { Linestring difference_midpoints; bg::midpoints(d, false, std::back_inserter(difference_midpoints)); diff --git a/test/srs/proj4.hpp b/test/srs/proj4.hpp index 10a7f4dd5..e59970136 100644 --- a/test/srs/proj4.hpp +++ b/test/srs/proj4.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2017-2019, Oracle and/or its affiliates. +// Copyright (c) 2017-2021, 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, @@ -14,6 +14,7 @@ #include #include +#include #if defined(TEST_WITH_PROJ6) #define TEST_WITH_PROJ5 @@ -152,30 +153,14 @@ struct pj_transformation forward(in_xy[i], out_xy[i]); } - template - void forward(In const& in, Out & out, - typename boost::enable_if_c - < - boost::is_same - < - typename boost::geometry::tag::type, - boost::geometry::point_tag - >::value - >::type* dummy = 0) const + template = 0> + void forward(In const& in, Out & out) const { transform_point(in, out, m_from, m_to); } - template - void inverse(In const& in, Out & out, - typename boost::enable_if_c - < - boost::is_same - < - typename boost::geometry::tag::type, - boost::geometry::point_tag - >::value - >::type* dummy = 0) const + template = 0> + void inverse(In const& in, Out & out) const { transform_point(in, out, m_to, m_from); } @@ -256,16 +241,8 @@ struct proj5_transformation out = std::move(in); } - template - void forward(In const& in, Out & out, - typename boost::enable_if_c - < - boost::is_same - < - typename boost::geometry::tag::type, - boost::geometry::point_tag - >::value - >::type* dummy = 0) const + template = 0> + void forward(In const& in, Out & out) const { PJ_COORD c; c.lp.lam = boost::geometry::get_as_radian<0>(in); @@ -300,16 +277,8 @@ struct proj6_transformation out = std::move(in); } - template - void forward(In const& in, Out & out, - typename boost::enable_if_c - < - boost::is_same - < - typename boost::geometry::tag::type, - boost::geometry::point_tag - >::value - >::type* dummy = 0) const + template = 0> + void forward(In const& in, Out & out) const { PJ_COORD c; c.lp.lam = boost::geometry::get_as_radian<0>(in); diff --git a/test/srs/projection_interface_s.cpp b/test/srs/projection_interface_s.cpp index 571eb3ac9..9e260bf05 100644 --- a/test/srs/projection_interface_s.cpp +++ b/test/srs/projection_interface_s.cpp @@ -82,8 +82,8 @@ int test_main(int, char*[]) // compile-time errors { - point_ll pt_ll(1, 1); - point_xy pt_xy(0, 0); + //point_ll pt_ll(1, 1); + //point_xy pt_xy(0, 0); //projection > prj1; //projection prj2; diff --git a/test/srs/spar.cpp b/test/srs/spar.cpp index c8650d8b8..76701f61a 100644 --- a/test/srs/spar.cpp +++ b/test/srs/spar.cpp @@ -1,7 +1,7 @@ // Boost.Geometry // Unit Test -// Copyright (c) 2018, Oracle and/or its affiliates. +// Copyright (c) 2018-2021, 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,30 +27,40 @@ int test_main(int, char* []) typedef par::o_proj o_proj; typedef par::guam guam; - BOOST_MPL_ASSERT_MSG((par::detail::is_param_tr::pred::value), - PROJ, (proj)); - BOOST_MPL_ASSERT_MSG((!par::detail::is_param_tr::pred::value), - NOT_PROJ, (int)); + BOOST_GEOMETRY_STATIC_ASSERT( + (par::detail::is_param_tr::pred::value), + "proj", proj); + BOOST_GEOMETRY_STATIC_ASSERT( + (!par::detail::is_param_tr::pred::value), + "not proj", int); - BOOST_MPL_ASSERT_MSG((par::detail::is_param_tr::pred::value), - ELLPS, (ellps)); - BOOST_MPL_ASSERT_MSG((!par::detail::is_param_tr::pred::value), - NOT_ELLPS, (int)); + BOOST_GEOMETRY_STATIC_ASSERT( + (par::detail::is_param_tr::pred::value), + "ellps", ellps); + BOOST_GEOMETRY_STATIC_ASSERT( + (!par::detail::is_param_tr::pred::value), + "not ellps", int); - BOOST_MPL_ASSERT_MSG((par::detail::is_param_tr::pred::value), - DATUM, (datum)); - BOOST_MPL_ASSERT_MSG((!par::detail::is_param_tr::pred::value), - NOT_DATUM, (int)); + BOOST_GEOMETRY_STATIC_ASSERT( + (par::detail::is_param_tr::pred::value), + "datum", datum); + BOOST_GEOMETRY_STATIC_ASSERT( + (!par::detail::is_param_tr::pred::value), + "not datum", int); - BOOST_MPL_ASSERT_MSG((par::detail::is_param_t::pred::value), - O_PROJ, (o_proj)); - BOOST_MPL_ASSERT_MSG((!par::detail::is_param_t::pred::value), - NOT_O_PROJ, (int)); + BOOST_GEOMETRY_STATIC_ASSERT( + (par::detail::is_param_t::pred::value), + "o_proj", o_proj); + BOOST_GEOMETRY_STATIC_ASSERT( + (!par::detail::is_param_t::pred::value), + "not o_proj", int); - BOOST_MPL_ASSERT_MSG((par::detail::is_param::pred::value), - GUAM, (guam)); - BOOST_MPL_ASSERT_MSG((!par::detail::is_param::pred::value), - NOT_GUAM, (int)); + BOOST_GEOMETRY_STATIC_ASSERT( + (par::detail::is_param::pred::value), + "guam", guam); + BOOST_GEOMETRY_STATIC_ASSERT( + (!par::detail::is_param::pred::value), + "not guam", int); typedef par::parameters params; typedef par::parameters params_e; diff --git a/test/strategies/distance.cpp b/test/strategies/distance.cpp index f4dd5381a..e2ff21944 100644 --- a/test/strategies/distance.cpp +++ b/test/strategies/distance.cpp @@ -1,8 +1,8 @@ // Boost.Geometry -// Copyright (c) 2017 Oracle and/or its affiliates. - +// Copyright (c) 2017-2021 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 // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -28,8 +28,8 @@ typedef bg::strategy::vincenty vincenty_formula; template bool non_precise_ct() { - typedef typename bg::coordinate_type

::type ct; - return boost::is_integral::value || boost::is_float::value; + using ct = typename bg::coordinate_type

::type; + return std::is_integral::value || std::is_floating_point::value; } template diff --git a/test/strategies/distance_default_result.cpp b/test/strategies/distance_default_result.cpp index 4ee721bbd..a51404cfa 100644 --- a/test/strategies/distance_default_result.cpp +++ b/test/strategies/distance_default_result.cpp @@ -1,9 +1,9 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2014, Oracle and/or its affiliates. - +// 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -17,10 +17,6 @@ #include -#include -#include -#include - #include #include @@ -35,17 +31,12 @@ namespace bg = ::boost::geometry; template -struct assert_equal_types +inline void assert_equal_types() { - assert_equal_types() - { - static const bool are_same = - boost::is_same::type::value; - - BOOST_MPL_ASSERT_MSG((are_same), - WRONG_DEFAULT_DISTANCE_RESULT, - (types)); - } + BOOST_GEOMETRY_STATIC_ASSERT( + (std::is_same::value), + "Wrong default distance result", + DefaultResult, ExpectedResult); }; //========================================================================= @@ -179,20 +170,20 @@ struct test_distance_result_box template inline void test_segment_all() { - typedef typename boost::mpl::if_ + using fp_return_type = std::conditional_t < - typename boost::is_same::type, + std::is_same::value, double, float - >::type float_return_type; + >; test_distance_result_segment(); test_distance_result_segment(); test_distance_result_segment(); test_distance_result_segment(); - test_distance_result_segment(); - test_distance_result_segment(); + test_distance_result_segment(); + test_distance_result_segment(); test_distance_result_segment(); test_distance_result_segment(); diff --git a/test/strategies/douglas_peucker.cpp b/test/strategies/douglas_peucker.cpp index c9216d555..c3a6193b9 100644 --- a/test/strategies/douglas_peucker.cpp +++ b/test/strategies/douglas_peucker.cpp @@ -2,7 +2,6 @@ // Unit Test // Copyright (c) 2015-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 @@ -24,11 +23,20 @@ #include #include +#include #include +#include + +#include +#include +#include #include #include +#include +#include + #include #include @@ -36,21 +44,8 @@ #include #include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - namespace bg = ::boost::geometry; -namespace ba = ::boost::assign; namespace services = bg::strategy::distance::services; typedef boost::tuple tuple_point_type; @@ -91,7 +86,7 @@ template inline Geometry from_wkt(std::string const& wkt) { Geometry geometry; - boost::geometry::read_wkt(wkt, geometry); + bg::read_wkt(wkt, geometry); return geometry; } @@ -151,14 +146,15 @@ struct equals template struct test_one_case { - template + using point_type = typename bg::point_type::type; + + template static inline void apply(std::string const& case_id, std::string const& wkt, double max_distance, Strategy const& strategy, - Range const& expected_result) + std::initializer_list const& expected_result) { - typedef typename bg::point_type::type point_type; std::vector result; Geometry geometry = from_wkt(wkt); @@ -227,7 +223,7 @@ inline void test_with_strategy(std::string label) "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -15,-12 5)", 10, strategy, - ba::tuple_list_of(12,-3)(4,8)(-6,-13)(-12,5) + {{12,-3},{4,8},{-6,-13},{-12,5}} ); } else @@ -236,7 +232,7 @@ inline void test_with_strategy(std::string label) "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -15,-12 5)", 10, strategy, - ba::tuple_list_of(12,-3)(4,8)(-6,-13)(-9,4)(0,-15)(-12,5) + {{12,-3},{4,8},{-6,-13},{-9,4},{0,-15},{-12,5}} ); } } @@ -245,21 +241,21 @@ inline void test_with_strategy(std::string label) "LINESTRING(-6 -13,-9 4,0 -15,-12 5)", 10, strategy, - ba::tuple_list_of(-6,-13)(-12,5) + {{-6,-13},{-12,5}} ); tester::apply("l03" + label, "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -14,-12 5)", 10, strategy, - ba::tuple_list_of(12,-3)(4,8)(-6,-13)(-12,5) + {{12,-3},{4,8},{-6,-13},{-12,5}} ); tester::apply("l04" + label, "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -14,-12 5)", 14, strategy, - ba::tuple_list_of(12,-3)(-6,-13)(-12,5) + {{12,-3},{-6,-13},{-12,5}} ); { @@ -306,13 +302,13 @@ inline void test_with_strategy(std::string label) wkt, 1, strategy, - ba::tuple_list_of(0,0)(5,0)(0,-1)(5,-1)(0,-2)(5,-2)(0,-3)(5,-4)(0,0) + {{0,0},{5,0},{0,-1},{5,-1},{0,-2},{5,-2},{0,-3},{5,-4},{0,0}} ); tester::apply("l05c1a" + label, wkt, 2, strategy, - ba::tuple_list_of(0,0)(5,0)(0,-1)(5,-1)(0,-2)(5,-4)(0,0) + {{0,0},{5,0},{0,-1},{5,-1},{0,-2},{5,-4},{0,0}} ); } else @@ -321,13 +317,13 @@ inline void test_with_strategy(std::string label) wkt, 1, strategy, - ba::tuple_list_of(0,0)(5,0)(0,-1)(5,-1)(0,-2)(5,-2)(0,-4)(5,-4)(0,0) + {{0,0},{5,0},{0,-1},{5,-1},{0,-2},{5,-2},{0,-4},{5,-4},{0,0}} ); tester::apply("l05c2a" + label, wkt, 2, strategy, - ba::tuple_list_of(0,0)(5,0)(0,-1)(5,-1)(0,-4)(5,-4)(0,0) + {{0,0},{5,0},{0,-1},{5,-1},{0,-4},{5,-4},{0,0}} ); } } diff --git a/test/strategies/pythagoras.cpp b/test/strategies/pythagoras.cpp index 66fd77634..bfa406160 100644 --- a/test/strategies/pythagoras.cpp +++ b/test/strategies/pythagoras.cpp @@ -5,6 +5,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -19,7 +23,8 @@ # pragma warning( disable : 4101 ) #endif -#include +// TODO move this to another non-unit test +//#include #include #include @@ -289,37 +294,38 @@ void test_all_3d() test_all_3d >(); } -template -void time_compare_s(int const n) -{ - boost::timer t; - P p1, p2; - bg::assign_values(p1, 1, 1); - bg::assign_values(p2, 2, 2); - Strategy strategy; - typename bg::strategy::distance::services::return_type::type s = 0; - for (int i = 0; i < n; i++) - { - for (int j = 0; j < n; j++) - { - bg::set<0>(p2, bg::get<0>(p2) + 0.001); - s += strategy.apply(p1, p2); - } - } - std::cout << "s: " << s << " t: " << t.elapsed() << std::endl; -} - -template -void time_compare(int const n) -{ - time_compare_s >(n); - time_compare_s >(n); -} +// TODO move this to another non-unit test +//template +//void time_compare_s(int const n) +//{ +// boost::timer t; +// P p1, p2; +// bg::assign_values(p1, 1, 1); +// bg::assign_values(p2, 2, 2); +// Strategy strategy; +// typename bg::strategy::distance::services::return_type::type s = 0; +// for (int i = 0; i < n; i++) +// { +// for (int j = 0; j < n; j++) +// { +// bg::set<0>(p2, bg::get<0>(p2) + 0.001); +// s += strategy.apply(p1, p2); +// } +// } +// std::cout << "s: " << s << " t: " << t.elapsed() << std::endl; +//} +// +//template +//void time_compare(int const n) +//{ +// time_compare_s >(n); +// time_compare_s >(n); +//} int test_main(int, char* []) { test_integer(true); - test_integer(true); + test_integer(true); test_integer(false); test_all_3d(); diff --git a/test/strategies/pythagoras_point_box.cpp b/test/strategies/pythagoras_point_box.cpp index 1596454d3..cc5a5fe25 100644 --- a/test/strategies/pythagoras_point_box.cpp +++ b/test/strategies/pythagoras_point_box.cpp @@ -5,9 +5,8 @@ // Copyright (c) 2008-2014 Bruno Lalande, Paris, France. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014-2020. -// Modifications copyright (c) 2014-2020, Oracle and/or its affiliates. - +// This file was modified by Oracle on 2014-2021. +// Modifications 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 @@ -29,7 +28,9 @@ #endif #include -#include + +// TODO move this to another non-unit test +//#include #include #include @@ -365,8 +366,8 @@ inline void test_integer(bool check_types) if (check_types) { - BOOST_CHECK((boost::is_same::type::value)); - BOOST_CHECK((boost::is_same::type::value)); + BOOST_CHECK((std::is_same::type::value)); + BOOST_CHECK((std::is_same::type::value)); } } @@ -394,41 +395,43 @@ void test_all_3d() test_all_3d >(); } -template -void time_compare_s(int const n) -{ - typedef bg::model::box

box_type; - boost::timer t; - P p; - box_type b; - bg::assign_values(b, 0, 0, 1, 1); - bg::assign_values(p, 2, 2); - Strategy strategy; - typename bg::strategy::distance::services::return_type - < - Strategy, P, box_type - >::type s = 0; - for (int i = 0; i < n; i++) - { - for (int j = 0; j < n; j++) - { - bg::set<0>(p, bg::get<0>(p) + 0.001); - s += strategy.apply(p, b); - } - } - std::cout << "s: " << s << " t: " << t.elapsed() << std::endl; -} - -template -inline void time_compare(int const n) -{ - time_compare_s >(n); - time_compare_s - < - P, bg::strategy::distance::comparable::pythagoras_point_box<> - >(n); -} +// TODO move this to another non-unit test +//template +//void time_compare_s(int const n) +//{ +// typedef bg::model::box

box_type; +// +// boost::timer t; +// P p; +// box_type b; +// bg::assign_values(b, 0, 0, 1, 1); +// bg::assign_values(p, 2, 2); +// Strategy strategy; +// typename bg::strategy::distance::services::return_type +// < +// Strategy, P, box_type +// >::type s = 0; +// for (int i = 0; i < n; i++) +// { +// for (int j = 0; j < n; j++) +// { +// bg::set<0>(p, bg::get<0>(p) + 0.001); +// s += strategy.apply(p, b); +// } +// } +// std::cout << "s: " << s << " t: " << t.elapsed() << std::endl; +//} +// +//template +//inline void time_compare(int const n) +//{ +// time_compare_s >(n); +// time_compare_s +// < +// P, bg::strategy::distance::comparable::pythagoras_point_box<> +// >(n); +//} @@ -436,7 +439,7 @@ inline void time_compare(int const n) BOOST_AUTO_TEST_CASE( test_integer_all ) { test_integer(true); - test_integer(true); + test_integer(true); test_integer(false); } diff --git a/test/strategies/vincenty.cpp b/test/strategies/vincenty.cpp index e0b0e4059..dd4e5f4d8 100644 --- a/test/strategies/vincenty.cpp +++ b/test/strategies/vincenty.cpp @@ -5,9 +5,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014, 2015, 2016, 2017. -// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. - +// This file was modified by Oracle on 2014-2021. +// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -96,8 +95,8 @@ double azimuth(double deg, double min) template bool non_precise_ct() { - typedef typename bg::coordinate_type

::type ct; - return boost::is_integral::value || boost::is_float::value; + using ct = typename bg::coordinate_type

::type; + return std::is_integral::value || std::is_floating_point::value; } template @@ -248,8 +247,8 @@ void test_all() // Test fractional coordinates only for non-integral types if ( BOOST_GEOMETRY_CONDITION( - ! boost::is_integral::type>::value - && ! boost::is_integral::type>::value ) ) + ! std::is_integral::type>::value + && ! std::is_integral::type>::value ) ) { // Flinders Peak -> Buninyong test_vincenty(azimuth(144,25,29.52440), azimuth(-37,57,3.72030), diff --git a/test/string_from_type.hpp b/test/string_from_type.hpp index 8d2bd6db8..6d02b8b15 100644 --- a/test/string_from_type.hpp +++ b/test/string_from_type.hpp @@ -4,10 +4,10 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. - +// This file was modified by Oracle on 2015-2021. +// Modifications copyright (c) 2015-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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -50,11 +50,9 @@ template <> struct string_from_type template <> struct string_from_type { static std::string name() { return "m"; } }; -#if defined(BOOST_HAS_LONG_LONG) // this is what g++ and clang++ use -template <> struct string_from_type +template <> struct string_from_type { static std::string name() { return "x"; } }; -#endif #if defined(BOOST_HAS_INT128) // this is what g++ and clang++ use diff --git a/test/test_common/test_point.hpp b/test/test_common/test_point.hpp index 31b124867..3f888a2f5 100644 --- a/test/test_common/test_point.hpp +++ b/test/test_common/test_point.hpp @@ -3,6 +3,11 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. + +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -60,7 +65,7 @@ template<> struct coordinate_system { typedef cs::cartesian type; }; template<> -struct dimension: boost::mpl::int_<3> {}; +struct dimension : std::integral_constant {}; template<> struct access { diff --git a/test/test_common/with_pointer.hpp b/test/test_common/with_pointer.hpp index 9c7b95db7..1e77e0e64 100644 --- a/test/test_common/with_pointer.hpp +++ b/test/test_common/with_pointer.hpp @@ -3,6 +3,11 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. + +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -48,7 +53,7 @@ template<> struct coordinate_type template<> struct coordinate_system { typedef cs::cartesian type; }; -template<> struct dimension : boost::mpl::int_<2> {}; +template<> struct dimension : std::integral_constant {}; template<> struct access diff --git a/test/test_geometries/custom_lon_lat_point.hpp b/test/test_geometries/custom_lon_lat_point.hpp index 1d49dcc00..5c0dc0d9d 100644 --- a/test/test_geometries/custom_lon_lat_point.hpp +++ b/test/test_geometries/custom_lon_lat_point.hpp @@ -1,9 +1,9 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2014, Oracle and/or its affiliates. - +// 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -11,8 +11,6 @@ #ifndef BOOST_GEOMETRY_TEST_TEST_GEOMETRIES_CUSTOM_LON_LAT_POINT_HPP #define BOOST_GEOMETRY_TEST_TEST_GEOMETRIES_CUSTOM_LON_LAT_POINT_HPP -#include - #include #include #include @@ -51,7 +49,7 @@ struct coordinate_system > template struct dimension > - : boost::mpl::int_<2> + : std::integral_constant {}; template @@ -109,7 +107,7 @@ struct coordinate_system > template struct dimension > - : boost::mpl::int_<2> + : std::integral_constant {}; template diff --git a/test/to_svg.hpp b/test/to_svg.hpp index 10c13f800..6897fcf96 100644 --- a/test/to_svg.hpp +++ b/test/to_svg.hpp @@ -2,32 +2,31 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014-2021. +// Modifications copyright (c) 2014-2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_TEST_TO_SVG_HPP #define BOOST_GEOMETRY_TEST_TO_SVG_HPP #include -#include -#include #include #include #include #include #include #include -#include - #include +#include +#include + + template inline void turns_to_svg(Turns const& turns, Mapper & mapper, bool /*enrich*/ = false) { @@ -42,7 +41,7 @@ inline void turns_to_svg(Turns const& turns, Mapper & mapper, bool /*enrich*/ = int index = 0; int const margin = 5; - BOOST_FOREACH(turn_info const& turn, turns) + for (turn_info const& turn : turns) { int lineheight = 10; mapper.map(turn.point, "fill:rgb(255,128,0);" diff --git a/test/util/calculation_type.cpp b/test/util/calculation_type.cpp index 6e026676f..7ddc989fb 100644 --- a/test/util/calculation_type.cpp +++ b/test/util/calculation_type.cpp @@ -5,6 +5,10 @@ // Copyright (c) 2012 Bruno Lalande, Paris, France. // Copyright (c) 2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -58,7 +62,7 @@ void test() std::string const caption = helper(); - BOOST_CHECK_MESSAGE((boost::is_same::type::value), + BOOST_CHECK_MESSAGE((std::is_same::value), "Failure, types do not agree;" << " input: " << caption << " defaults: " << typeid(DefaultFP).name() @@ -88,7 +92,7 @@ void test_with_calculation_type() std::string const caption = helper(); - BOOST_CHECK_MESSAGE((boost::is_same::type::value), + BOOST_CHECK_MESSAGE((std::is_same::value), "Failure, types do not agree;" << " input: " << caption << " calculation type: " << typeid(CalculationType).name() @@ -114,7 +118,7 @@ void test_unary() DefaultInt >::type type; - BOOST_CHECK_MESSAGE((boost::is_same::type::value), + BOOST_CHECK_MESSAGE((std::is_same::value), "Failure, types do not agree;" << " input: " << typeid(typename bg::coordinate_type::type).name() << " defaults: " << typeid(DefaultFP).name() @@ -148,7 +152,7 @@ void test_ternary() std::string const caption = helper3(); - BOOST_CHECK_MESSAGE((boost::is_same::type::value), + BOOST_CHECK_MESSAGE((std::is_same::value), "Failure, types do not agree;" << " input: " << caption << " defaults: " << typeid(DefaultFP).name() @@ -169,7 +173,7 @@ int test_main(int, char* []) typedef model::point i; typedef model::point c; typedef model::point s; - typedef model::point ll; + typedef model::point ll; typedef model::point u; // Calculation type "void" so @@ -187,11 +191,11 @@ int test_main(int, char* []) test(); test(); test(); - test(); + test(); // Even if we specify "int" as default-calculation-type, it should never go downwards. // So it will select "long long" - test(); + test(); // user defined test(); diff --git a/test/util/is_implemented.cpp b/test/util/is_implemented.cpp index 3eed994b4..dd6e09b0f 100644 --- a/test/util/is_implemented.cpp +++ b/test/util/is_implemented.cpp @@ -74,14 +74,14 @@ int test_main(int, char* []) typedef bg::model::d2::point_xy point_type; BOOST_MPL_ASSERT(( - boost::is_same< + std::is_same< bg::util::is_implemented2 < point_type, point_type, bg::algorithm_archetype >::type, boost::mpl::false_ - > + >::value )); return 0; diff --git a/test/util/math_sqrt.cpp b/test/util/math_sqrt.cpp index 0907990ab..e06bc05af 100644 --- a/test/util/math_sqrt.cpp +++ b/test/util/math_sqrt.cpp @@ -1,9 +1,9 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2014, Oracle and/or its affiliates. - +// 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -14,11 +14,11 @@ #include #include +#include #include #include -#include #include "number_types.hpp" @@ -26,8 +26,8 @@ // otherwise the test will fail for the custom number type: // custom_with_global_sqrt -#include #include +#include namespace bg = boost::geometry; @@ -35,68 +35,44 @@ namespace bg = boost::geometry; // call BOOST_CHECK -template -struct check +template +< + typename Argument, typename Result, + std::enable_if_t::value, int> = 0 +> +inline void check(Argument const& arg, Result const& result) { - template - static inline void apply(Argument const& arg, Result const& result) - { - BOOST_CHECK_CLOSE(static_cast(bg::math::sqrt(arg)), - static_cast(result), - 0.00001); - } -}; + BOOST_CHECK_CLOSE(static_cast(bg::math::sqrt(arg)), + static_cast(result), + 0.00001); +} - -template -struct check +template +< + typename Argument, typename Result, + std::enable_if_t::value, int> = 0 +> +inline void check(Argument const& arg, Result const& result) { - template - static inline void apply(Argument const& arg, Result const& result) - { - Result const tol(0.00001); - BOOST_CHECK( bg::math::abs(bg::math::sqrt(arg) - result) < tol ); - } -}; - - - - + Result const tol(0.00001); + BOOST_CHECK( bg::math::abs(bg::math::sqrt(arg) - result) < tol ); +} // test sqrt return type and value -template -< - typename Argument, - typename ExpectedResult, - typename Result = typename bg::math::detail::square_root - < - Argument - >::return_type, - bool IsFundamental = boost::is_fundamental::value -> -struct check_sqrt - : bg::not_implemented -{}; - - -template -struct check_sqrt +template +inline void check_sqrt(Argument const& arg, Result const& result) { - static inline void apply(Argument const& arg, Result const& result) - { + using return_type = typename bg::math::detail::square_root::return_type; + BOOST_GEOMETRY_STATIC_ASSERT((std::is_same::value), "Wrong return type"); + #ifdef BOOST_GEOMETRY_TEST_DEBUG - std::cout << "testing: " << typeid(Result).name() - << " sqrt(" << typeid(Argument).name() - << ")" << std::endl; + std::cout << "testing: " << typeid(Result).name() + << " sqrt(" << typeid(Argument).name() + << ")" << std::endl; #endif - check::apply(arg, result); - } -}; - - - - + check(arg, result); +} // test cases @@ -106,24 +82,17 @@ BOOST_AUTO_TEST_CASE( test_math_sqrt_fundamental ) static const long double sqrt2L = std::sqrt(2.0L); static const float sqrt2F = std::sqrt(2.0F); - check_sqrt::apply(2.0F, sqrt2F); - check_sqrt::apply(2.0, sqrt2); - check_sqrt::apply(2.0L, sqrt2L); + check_sqrt(2.0F, sqrt2F); + check_sqrt(2.0, sqrt2); + check_sqrt(2.0L, sqrt2L); - check_sqrt::apply(2, sqrt2); - check_sqrt::apply(2, sqrt2); - check_sqrt::apply(2, sqrt2); - check_sqrt::apply(2, sqrt2); - check_sqrt::apply(2L, sqrt2); -#if !defined(BOOST_NO_LONG_LONG) - check_sqrt::apply(2LL, sqrt2); -#endif -#ifdef BOOST_HAS_LONG_LONG - check_sqrt - < - boost::long_long_type, double - >::apply(boost::long_long_type(2), sqrt2); -#endif + check_sqrt(2, sqrt2); + check_sqrt(2, sqrt2); + check_sqrt(2, sqrt2); + check_sqrt(2, sqrt2); + check_sqrt(2L, sqrt2); + + check_sqrt(2LL, sqrt2); } @@ -135,7 +104,7 @@ BOOST_AUTO_TEST_CASE( test_math_sqrt_custom ) static const double sqrt2 = std::sqrt(2.0); - check_sqrt::apply(custom1(2.0), custom1(sqrt2)); - check_sqrt::apply(custom2(2.0), custom2(sqrt2)); - check_sqrt::apply(custom3(2.0), custom3(sqrt2)); + check_sqrt(custom1(2.0), custom1(sqrt2)); + check_sqrt(custom2(2.0), custom2(sqrt2)); + check_sqrt(custom3(2.0), custom3(sqrt2)); } diff --git a/test/util/promote_integral.cpp b/test/util/promote_integral.cpp index 670f78904..babad6491 100644 --- a/test/util/promote_integral.cpp +++ b/test/util/promote_integral.cpp @@ -1,8 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2015-2020, Oracle and/or its affiliates. - +// Copyright (c) 2015-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 @@ -290,12 +289,10 @@ struct test_promotion { tester::template apply(case_id); } -#if defined(BOOST_HAS_LONG_LONG) - else if (bit_size() >= min_size) + else if (bit_size() >= min_size) { - tester::template apply(case_id); + tester::template apply(case_id); } -#endif #if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128) else if (bit_size() >= min_size) { @@ -360,12 +357,10 @@ struct test_promotion { tester::apply(case_id); } -#if defined(BOOST_HAS_LONG_LONG) - else if (bit_size() >= min_size) + else if (bit_size() >= min_size) { - tester::template apply(case_id); + tester::template apply(case_id); } -#endif #if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128) else if (bit_size() >= min_size) { @@ -438,15 +433,13 @@ BOOST_AUTO_TEST_CASE( test_std_size_t ) test_promotion::apply("size_t"); } -#ifdef BOOST_HAS_LONG_LONG BOOST_AUTO_TEST_CASE( test_long_long ) { - test_promotion::apply("long long"); - test_promotion::apply("long long"); - test_promotion::apply("ulong long"); - test_promotion::apply("ulong long"); + test_promotion::apply("long long"); + test_promotion::apply("long long"); + test_promotion::apply("ulong long"); + test_promotion::apply("ulong long"); } -#endif #if defined(BOOST_HAS_INT128) && defined(BOOST_GEOMETRY_ENABLE_INT128) BOOST_AUTO_TEST_CASE( test_int128 ) diff --git a/test/util/select_most_precise.cpp b/test/util/select_most_precise.cpp index 3ec2dec73..c4146089c 100644 --- a/test/util/select_most_precise.cpp +++ b/test/util/select_most_precise.cpp @@ -5,6 +5,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -23,8 +27,8 @@ struct user_defined {}; template void test() { - typedef typename bg::select_most_precise::type type; - bool is_same = boost::is_same::type::value; + using type = typename bg::select_most_precise::type; + bool is_same = std::is_same::value; BOOST_CHECK_MESSAGE(is_same, "The most precise of types " << From 14df20453fa456b7eb8f1e140b5d09ad8d205651 Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 21 Jul 2021 18:56:23 +0200 Subject: [PATCH 13/74] [test] remove the non used KRAMER define and rephrase/include/exclude some tests --- include/boost/geometry/core/config.hpp | 6 +- .../set_operations/difference/difference.cpp | 160 +++++++++--------- .../difference/difference_multi.cpp | 34 ++-- .../difference/test_difference.hpp | 15 +- .../intersection/intersection.cpp | 4 +- .../intersection/intersection_multi.cpp | 8 +- .../set_operations/union/union_multi.cpp | 17 +- test/geometry_test_common.hpp | 15 +- 8 files changed, 117 insertions(+), 142 deletions(-) diff --git a/include/boost/geometry/core/config.hpp b/include/boost/geometry/core/config.hpp index 1c6fab8e0..3066586c4 100644 --- a/include/boost/geometry/core/config.hpp +++ b/include/boost/geometry/core/config.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2019 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2019-2021 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2018-2020 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -23,10 +23,6 @@ #define BOOST_GEOMETRY_CXX11_TUPLE #endif -// Defining this selects Kramer rule for segment-intersection -// That is default behaviour. -#define BOOST_GEOMETRY_USE_KRAMER_RULE - // Rescaling is turned on, unless NO_ROBUSTNESS is defined // In future versions of Boost.Geometry, it will be turned off by default #if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS) diff --git a/test/algorithms/set_operations/difference/difference.cpp b/test/algorithms/set_operations/difference/difference.cpp index 0565f47aa..9e2db27d0 100644 --- a/test/algorithms/set_operations/difference/difference.cpp +++ b/test/algorithms/set_operations/difference/difference.cpp @@ -48,19 +48,10 @@ void test_all() typedef typename bg::coordinate_type

::type ct; - ut_settings sym_settings; -#if ! defined(BOOST_GEOMETRY_USE_RESCALING) - sym_settings.sym_difference = false; -#endif - - ut_settings ignore_validity_settings; - ignore_validity_settings.set_test_validity(false); - test_one("simplex_normal", simplex_normal[0], simplex_normal[1], 3, 12, 2.52636706856656, - 3, 12, 3.52636706856656, - sym_settings); + 3, 12, 3.52636706856656); test_one("simplex_with_empty", simplex_normal[0], polygon_empty, @@ -70,8 +61,7 @@ void test_all() test_one( "star_ring", example_star, example_ring, 5, 22, 1.1901714, - 5, 27, 1.6701714, - sym_settings); + 5, 27, 1.6701714); test_one("two_bends", two_bends[0], two_bends[1], @@ -81,8 +71,7 @@ void test_all() test_one("star_comb_15", star_comb_15[0], star_comb_15[1], 30, -1, 227.658275102812, - 30, -1, 480.485775259312, - sym_settings); + 30, -1, 480.485775259312); test_one("new_hole", new_hole[0], new_hole[1], @@ -115,17 +104,22 @@ void test_all() 1, 5, 9.0, 1, 5, 9.0); - test_one("only_hole_intersections1", - only_hole_intersections[0], only_hole_intersections[1], - 2, 10, 1.9090909, - 4, 16, 10.9090909, - sym_settings); + { + ut_settings settings; + settings.sym_difference_validity = BG_IF_RESCALED(true, false); - test_one("only_hole_intersection2", - only_hole_intersections[0], only_hole_intersections[2], - 3, 20, 30.9090909, - 4, 16, 10.9090909, - sym_settings); + test_one("only_hole_intersections1", + only_hole_intersections[0], only_hole_intersections[1], + 2, 10, 1.9090909, + 4, 16, 10.9090909, + settings); + + test_one("only_hole_intersection2", + only_hole_intersections[0], only_hole_intersections[2], + 3, 20, 30.9090909, + 4, 16, 10.9090909, + settings); + } test_one("first_within_second", first_within_second[1], first_within_second[0], @@ -148,20 +142,24 @@ void test_all() 4, 20, 11.533333, 5, 26, 29.783333); - test_one("intersect_holes_intersect_and_disjoint", - intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1], - 2, 16, 15.75, - 3, 17, 6.75, - ignore_validity_settings); + { + ut_settings settings; + settings.sym_difference_validity = BG_IF_RESCALED(false, true); + test_one("intersect_holes_intersect_and_disjoint", + intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1], + 2, 16, 15.75, + 3, 17, 6.75, + settings); - test_one("intersect_holes_intersect_and_touch", - intersect_holes_intersect_and_touch[0], intersect_holes_intersect_and_touch[1], - 3, 21, 16.25, - 3, 17, 6.25, - ignore_validity_settings); + test_one("intersect_holes_intersect_and_touch", + intersect_holes_intersect_and_touch[0], intersect_holes_intersect_and_touch[1], + 3, 21, 16.25, + 3, 17, 6.25, + settings); + } { - ut_settings settings = sym_settings; + ut_settings settings; settings.percentage = 0.01; test_one("intersect_holes_new_ring", intersect_holes_new_ring[0], intersect_holes_new_ring[1], @@ -180,17 +178,20 @@ void test_all() 2, 14, 16.0, 2, 10, 6.0); - test_one("intersect_holes_intersect", - intersect_holes_intersect[0], intersect_holes_intersect[1], - 2, 16, 15.75, - 2, 12, 5.75, - ignore_validity_settings); + { + ut_settings settings; + settings.sym_difference_validity = BG_IF_RESCALED(false, true); + test_one("intersect_holes_intersect", + intersect_holes_intersect[0], intersect_holes_intersect[1], + 2, 16, 15.75, + 2, 12, 5.75, + settings); + } test_one( "case4", case_4[0], case_4[1], 6, 28, 2.77878787878788, - 4, 22, 4.77878787878788, - sym_settings); + 4, 22, 4.77878787878788); test_one( "case5", case_5[0], case_5[1], @@ -248,7 +249,8 @@ void test_all() TEST_DIFFERENCE(case_precision_9, optional(), optional_sliver(), 1, 59.0, count_set(1, 2)); TEST_DIFFERENCE_WITH(case_precision_10, optional(), optional_sliver(), 1, 59, count_set(1, 2), ut_settings(0.001)); -#if ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES) +#if defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) + // Fails without rescaling TEST_DIFFERENCE(case_precision_11, optional(), optional_sliver(), 1, 59.0, count_set(1, 2)); #endif @@ -295,12 +297,10 @@ void test_all() if ( BOOST_GEOMETRY_CONDITION((boost::is_same::value)) ) { - test_one("buffer_mp2", - buffer_mp2[0], buffer_mp2[1], - 1, 91, 12.09857, - 1, 155, 24.19714, - {1, 2}, -1, 12.09857 + 24.19714, - sym_settings); + ut_settings settings; + settings.sym_difference_validity = BG_IF_RESCALED(true, false); + TEST_DIFFERENCE_WITH(buffer_mp2, 1, 12.09857, 1, 24.19714, + count_set(1, 2), settings); } /*** TODO: self-tangencies for difference @@ -364,14 +364,12 @@ void test_all() geos_3[0], geos_3[1], 1, -1, 16211128.5, 1, -1, 13180420.0, - {1, 2}, -1, 16211128.5 + 13180420.0, - sym_settings); + {1, 2}, -1, 16211128.5 + 13180420.0); test_one("geos_4", geos_4[0], geos_4[1], 1, -1, 971.9163115, - 1, -1, 1332.4163115, - sym_settings); + 1, -1, 1332.4163115); test_one("ggl_list_20110306_javier", ggl_list_20110306_javier[0], ggl_list_20110306_javier[1], @@ -391,16 +389,15 @@ void test_all() 1, 58456.4964294434, 1); -#if defined(BOOST_GEOMETRY_USE_RESCALING) \ - || ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) \ - || defined(BOOST_GEOMETRY_TEST_FAILURES) + { + ut_settings settings(0.0001, false); // Symmetric difference should output one polygon // Using rescaling, it currently outputs two. TEST_DIFFERENCE_WITH(ggl_list_20110820_christophe, 1, 2.8570121719168924, 1, 64.498061986388564, - count_set(1, 2), ut_settings(0.0001, false)); -#endif + count_set(1, 2), settings); + } test_one("ggl_list_20120717_volker", ggl_list_20120717_volker[0], ggl_list_20120717_volker[1], @@ -428,6 +425,7 @@ void test_all() // With rescaling, difference of output a-b and a sym b is invalid ut_settings settings; settings.set_test_validity(BG_IF_RESCALED(false, true)); + settings.sym_difference_validity = BG_IF_RESCALED(false, true); TEST_DIFFERENCE_WITH(ggl_list_20190307_matthieu_1, count_set(1, 2), 0.18461532, count_set(1, 2), 0.617978, @@ -472,8 +470,7 @@ void test_all() test_one("ticket_10108_a", ticket_10108_a[0], ticket_10108_a[1], 1, 4, {0.0145036, 0.0145037}, - 1, 4, 0.029019232, - sym_settings); + 1, 4, 0.029019232); #endif test_one("ticket_10108_b", @@ -504,14 +501,12 @@ void test_all() test_one( "star_ring_ring", example_star, example_ring, 5, 22, 1.1901714, - 5, 27, 1.6701714, - sym_settings); + 5, 27, 1.6701714); test_one( "ring_star_ring", example_ring, example_star, 5, 27, 1.6701714, - 5, 22, 1.1901714, - sym_settings); + 5, 22, 1.1901714); static std::string const clip = "POLYGON((2.5 0.5,5.5 2.5))"; @@ -530,18 +525,15 @@ void test_all() test_one( "star_ring_ccw", example_star, example_ring, 5, 22, 1.1901714, - 5, 27, 1.6701714, - sym_settings); + 5, 27, 1.6701714); test_one( "star_ring_ccw1", example_star, example_ring, 5, 22, 1.1901714, - 5, 27, 1.6701714, - sym_settings); + 5, 27, 1.6701714); test_one( "star_ring_ccw2", example_star, example_ring, 5, 22, 1.1901714, - 5, 27, 1.6701714, - sym_settings); + 5, 27, 1.6701714); } // Multi/box (should be moved to multi) @@ -568,10 +560,15 @@ void test_all() optional(), optional_sliver(1.0e-5), count_set(1, 2)); - TEST_DIFFERENCE(issue_838, - count_set(1, 2), expectation_limits(0.000026, 0.0002823), - count_set(1, 2), expectation_limits(0.67257, 0.67499), - count_set(2, 3, 4)); + { + ut_settings settings; + settings.set_test_validity(BG_IF_RESCALED(true, false)); + TEST_DIFFERENCE_WITH(issue_838, + count_set(1, 2), expectation_limits(0.000026, 0.0002823), + count_set(1, 2), expectation_limits(0.67257, 0.67499), + count_set(2, 3, 4), + settings); + } TEST_DIFFERENCE(mysql_21977775, 2, 160.856568913, 2, 92.3565689126, 4); TEST_DIFFERENCE(mysql_21965285, 1, 92.0, 1, 14.0, 1); @@ -579,13 +576,13 @@ void test_all() TEST_DIFFERENCE(mysql_23023665_2, 1, 96.0, 1, 16.0, 2); TEST_DIFFERENCE(mysql_23023665_3, 1, 225.0, 1, 66.0, 2); TEST_DIFFERENCE(mysql_23023665_5, 2, 165.23735, 2, 105.73735, 4); -#if defined(BOOST_GEOMETRY_USE_RESCALING) \ - || ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) \ - || defined(BOOST_GEOMETRY_TEST_FAILURES) - // Testcases going wrong with Kramer's rule and no rescaling - TEST_DIFFERENCE(mysql_23023665_6, 2, 105.68756, 3, 10.18756, 5); + { + // Without recaling it is invalid + ut_settings settings; + settings.set_test_validity(BG_IF_RESCALED(true, false)); + TEST_DIFFERENCE_WITH(mysql_23023665_6, 2, 105.68756, 3, 10.18756, 5, settings); + } TEST_DIFFERENCE(mysql_23023665_13, 3, 99.74526, 3, 37.74526, 6); -#endif } @@ -629,7 +626,8 @@ int test_main(int, char* []) #if defined(BOOST_GEOMETRY_TEST_FAILURES) // Not yet fully tested for float and long double. // The difference algorithm can generate (additional) slivers - BoostGeometryWriteExpectedFailures(12, 5, 11, 6); + // Many of the failures are self-intersection points. + BoostGeometryWriteExpectedFailures(12, 10, 17, 12); #endif return 0; diff --git a/test/algorithms/set_operations/difference/difference_multi.cpp b/test/algorithms/set_operations/difference/difference_multi.cpp index 410a89d8e..af45b0d4f 100644 --- a/test/algorithms/set_operations/difference/difference_multi.cpp +++ b/test/algorithms/set_operations/difference/difference_multi.cpp @@ -152,25 +152,19 @@ void test_areal() TEST_DIFFERENCE_WITH(0, 1, ggl_list_20120221_volker, 2, 7962.66, 2, 2775258.93, 4); } +#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) { - // With rescaling, A is invalid (this is a robustness problem) and the other - // output is discarded because of zero area - // POSTGIS areas: 3.75893745345145, 2.5810000723917e-15 + // 1: Very small sliver for B (discarded when rescaling) + // 2: sym difference is not considered as valid + // 3: with rescaling A is considered as invalid (robustness problem) ut_settings settings; - settings.sym_difference = BG_IF_RESCALED(false, true); - settings.set_test_validity(BG_IF_RESCALED(false, true)); -#if defined(BOOST_GEOMETRY_USE_RESCALING) || ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) - // No output for B - TEST_DIFFERENCE_WITH(0, 1, bug_21155501, 1, 3.758937, 0, 0.0, 1); -#else - // Very small sliver for B, and sym difference is not considered valid - settings.set_test_validity(false); + settings.sym_difference_validity = false; TEST_DIFFERENCE_WITH(0, 1, bug_21155501, (count_set(1, 4)), expectation_limits(3.75893, 3.75894), (count_set(1, 4)), (expectation_limits(1.776357e-15, 7.661281e-15)), (count_set(2, 5))); -#endif } +#endif #if defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) { @@ -178,6 +172,7 @@ void test_areal() // Without rescaling, one ring is missing (for a and s) ut_settings settings; settings.set_test_validity(BG_IF_RESCALED(false, true)); + settings.sym_difference_validity = BG_IF_RESCALED(false, true); TEST_DIFFERENCE_WITH(0, 1, ticket_9081, 2, 0.0907392476356186, 4, 0.126018011439877, @@ -400,14 +395,14 @@ void test_areal() TEST_DIFFERENCE(case_precision_m2, count_set(1, 2), 1.0, 1, 57.75, count_set(2, 3)); { - ut_settings sym_settings; - sym_settings.sym_difference = BG_IF_RESCALED(true, BG_IF_TEST_FAILURES); + ut_settings settings; + settings.sym_difference = BG_IF_RESCALED(true, BG_IF_TEST_FAILURES); test_one("mysql_21965285_b", mysql_21965285_b[0], mysql_21965285_b[1], 2, -1, 183.71376870369406, 2, -1, 131.21376870369406, - sym_settings); + settings); } TEST_DIFFERENCE(mysql_regression_1_65_2017_08_31, @@ -473,10 +468,6 @@ void test_specific_areal() } { -#if defined(BOOST_GEOMETRY_USE_KRAMER) || defined(BOOST_GEOMETRY_TEST_FAILURES) - // Fails completely with general line form intersection - // There is something with scale. - // TODO GENERAL FORM const std::string a_min_b = TEST_DIFFERENCE(ticket_10661, 2, 1441632.5, 2, 13167454, 4); @@ -485,17 +476,14 @@ void test_specific_areal() 1, 8, 825192.0, 1, 10, expectation_limits(27226370, 27842812), 1, -1, 825192.0 + 27226370.5); -#endif } { ut_settings settings; settings.sym_difference = false; -#if defined(BOOST_GEOMETRY_USE_KRAMER) || defined(BOOST_GEOMETRY_TEST_FAILURES) TEST_DIFFERENCE_WITH(0, 1, ticket_9942, 4, expectation_limits(7427727.5), 4, expectation_limits(130083, 131507), 4); -#endif TEST_DIFFERENCE_WITH(0, 1, ticket_9942a, 2, expectation_limits(412676, 413184), 2, expectation_limits(76779, 76925), 4); @@ -525,7 +513,7 @@ int test_main(int, char* []) #if defined(BOOST_GEOMETRY_TEST_FAILURES) // Not yet fully tested for float. // The difference algorithm can generate (additional) slivers - BoostGeometryWriteExpectedFailures(22, 12, 16, 7); + BoostGeometryWriteExpectedFailures(28, 15, 19, 10); #endif return 0; diff --git a/test/algorithms/set_operations/difference/test_difference.hpp b/test/algorithms/set_operations/difference/test_difference.hpp index 3c9ce08a5..0c01d94cb 100644 --- a/test/algorithms/set_operations/difference/test_difference.hpp +++ b/test/algorithms/set_operations/difference/test_difference.hpp @@ -65,13 +65,13 @@ struct ut_settings : ut_base_settings { double percentage; bool sym_difference; - bool remove_spikes; + bool sym_difference_validity = true; + bool remove_spikes = false; - explicit ut_settings(double p = 0.0001, bool tv = true, bool sd = true) - : ut_base_settings(tv) + explicit ut_settings(double p = 0.0001, bool validity = true, bool sd = true) + : ut_base_settings(validity) , percentage(p) , sym_difference(sd) - , remove_spikes(false) {} }; @@ -192,7 +192,12 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g typename bg::default_area_result::type const area = bg::area(result); #if ! defined(BOOST_GEOMETRY_NO_BOOST_TEST) - if (settings.test_validity()) + bool const test_validity + = sym + ? (settings.sym_difference_validity || BG_IF_TEST_FAILURES) + : settings.test_validity(); + + if (test_validity) { // std::cout << bg::dsv(result) << std::endl; typedef bg::model::multi_polygon result_type; diff --git a/test/algorithms/set_operations/intersection/intersection.cpp b/test/algorithms/set_operations/intersection/intersection.cpp index d2b93b7e2..38a2272d2 100644 --- a/test/algorithms/set_operations/intersection/intersection.cpp +++ b/test/algorithms/set_operations/intersection/intersection.cpp @@ -232,10 +232,8 @@ void test_areal() TEST_INTERSECTION(ggl_list_20190307_matthieu_1, 2, -1, 0.035136); TEST_INTERSECTION(ggl_list_20190307_matthieu_2, 1, -1, 3.64285); -#if defined(BOOST_GEOMETRY_USE_RESCALING) || ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES) test_one("buffer_rt_f", buffer_rt_f[0], buffer_rt_f[1], 1, 4, expectation_limits(0.00029437, 0.000294380)); -#endif test_one("buffer_rt_g", buffer_rt_g[0], buffer_rt_g[1], 1, 0, 2.914213562373); @@ -950,7 +948,7 @@ int test_main(int, char* []) #if defined(BOOST_GEOMETRY_TEST_FAILURES) // llb_touch generates a polygon with 1 point and is therefore invalid everywhere // TODO: this should be easy to fix - BoostGeometryWriteExpectedFailures(5, 2, 6, 1); + BoostGeometryWriteExpectedFailures(6, 2, 7, 1); #endif return 0; diff --git a/test/algorithms/set_operations/intersection/intersection_multi.cpp b/test/algorithms/set_operations/intersection/intersection_multi.cpp index 1edbdd6f4..48cd5f73f 100644 --- a/test/algorithms/set_operations/intersection/intersection_multi.cpp +++ b/test/algorithms/set_operations/intersection/intersection_multi.cpp @@ -367,13 +367,13 @@ void test_areal() // Result is wrong with rescaling TEST_INTERSECTION(issue_630_a, 1, -1, 0.1770); #endif -#if ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES) - // Two cases produce either too large, or no output if Kramer rule is used + TEST_INTERSECTION(issue_630_b, 1, -1, expectation_limits(0.1713911, 0.1714)); - TEST_INTERSECTION(issue_630_c, 1, -1, 0.1770); -#endif #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) + // Result is missing with rescaling + TEST_INTERSECTION(issue_630_c, 1, -1, 0.1770); + // Result is missing with rescaling TEST_INTERSECTION(issue_643, 1, -1, 3.4615); #endif diff --git a/test/algorithms/set_operations/union/union_multi.cpp b/test/algorithms/set_operations/union/union_multi.cpp index b7d9c725f..e80c72da3 100644 --- a/test/algorithms/set_operations/union/union_multi.cpp +++ b/test/algorithms/set_operations/union/union_multi.cpp @@ -422,13 +422,13 @@ void test_areal() // Failure with rescaling TEST_UNION(issue_630_a, 1, 0, -1, 2.200326); #endif + TEST_UNION(issue_630_b, 1, 0, -1, 1.675976); -#if ! defined(BOOST_GEOMETRY_USE_KRAMER_RULE) || defined(BOOST_GEOMETRY_TEST_FAILURES) - // Failure with Kramer rule, it doesn't generate any output - TEST_UNION(issue_630_c, 1, 0, -1, 1.670367); -#endif #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) + // With rescaling the smaller rectangle is added on top of the outer polygon + TEST_UNION(issue_630_c, 1, 0, -1, 1.670367); + // With rescaling the small polygon is added on top of the outer polygon TEST_UNION(issue_643, 1, 0, -1, 80.0); #endif @@ -441,13 +441,8 @@ void test_areal() TEST_UNION(issue_888_34, 15, 0, -1, 0.3017459); TEST_UNION(issue_888_37, 52, 3, -1, 0.4033294); -#if defined(BOOST_GEOMETRY_USE_KRAMER_RULE) - // Two polygons, should ideally be merged - TEST_UNION(mail_2019_01_21_johan, 2, 0, -1, 0.00058896); -#else - // Correct: one polygon - TEST_UNION(mail_2019_01_21_johan, 1, 0, -1, 0.00058896); -#endif + // One or two polygons, the ideal case is 1 + TEST_UNION(mail_2019_01_21_johan, count_set(1, 2), 0, -1, 0.00058896); TEST_UNION(mysql_23023665_7, 1, 1, -1, 99.19494); TEST_UNION(mysql_23023665_8, 1, 2, -1, 1400.0); diff --git a/test/geometry_test_common.hpp b/test/geometry_test_common.hpp index 96866bde3..78928a599 100644 --- a/test/geometry_test_common.hpp +++ b/test/geometry_test_common.hpp @@ -132,18 +132,18 @@ struct mathematical_policy struct ut_base_settings { - explicit ut_base_settings(bool val = true) + explicit ut_base_settings(bool validity = true) : m_test_validity(true) { - set_test_validity(val); + set_test_validity(validity); } - inline void set_test_validity(bool val) + inline void set_test_validity(bool validity) { #if defined(BOOST_GEOMETRY_TEST_FAILURES) - boost::ignore_unused(val); + boost::ignore_unused(validity); #else - m_test_validity = val; + m_test_validity = validity; #endif } @@ -207,11 +207,6 @@ inline void BoostGeometryWriteTestConfiguration() #if defined(BOOST_GEOMETRY_USE_RESCALING) std::cout << " - Using rescaling" << std::endl; #endif -#if defined(BOOST_GEOMETRY_USE_KRAMER_RULE) - std::cout << " - Using Kramer rule" << std::endl; -#else - std::cout << " - Using general form" << std::endl; -#endif #if defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) std::cout << " - Testing only one type" << std::endl; #endif From 01f8e23b0c2e1fa2871213f457995395825a02bc Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Thu, 8 Jul 2021 12:51:01 +0200 Subject: [PATCH 14/74] [traverse] reverse meaning of isolation in difference --- .../detail/overlay/is_self_turn.hpp | 3 +- .../algorithms/detail/overlay/traversal.hpp | 102 ++++++++++-------- .../overlay/traversal_switch_detector.hpp | 49 +++++++-- .../algorithms/detail/overlay/turn_info.hpp | 5 + .../difference/difference_multi.cpp | 6 +- .../difference/test_difference.hpp | 13 ++- 6 files changed, 114 insertions(+), 64 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/is_self_turn.hpp b/include/boost/geometry/algorithms/detail/overlay/is_self_turn.hpp index 448c04404..1606c31e9 100644 --- a/include/boost/geometry/algorithms/detail/overlay/is_self_turn.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/is_self_turn.hpp @@ -26,8 +26,7 @@ struct is_self_turn_check template static inline bool apply(Turn const& turn) { - return turn.operations[0].seg_id.source_index - == turn.operations[1].seg_id.source_index; + return turn.is_self(); } }; diff --git a/include/boost/geometry/algorithms/detail/overlay/traversal.hpp b/include/boost/geometry/algorithms/detail/overlay/traversal.hpp index a0149789c..b65f00424 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal.hpp @@ -621,31 +621,32 @@ public : return m_turns[rp.turn_index].operations[rp.operation_index]; } - inline sort_by_side::rank_type select_rank(sbs_type const& sbs, - bool skip_isolated) const + inline sort_by_side::rank_type select_rank(sbs_type const& sbs) const { + static bool const is_intersection + = target_operation == operation_intersection; + // Take the first outgoing rank corresponding to incoming region, // or take another region if it is not isolated - turn_operation_type const& incoming_op - = operation_from_rank(sbs.m_ranked_points.front()); + auto const& in_op = operation_from_rank(sbs.m_ranked_points.front()); for (std::size_t i = 0; i < sbs.m_ranked_points.size(); i++) { - typename sbs_type::rp const& rp = sbs.m_ranked_points[i]; + auto const& rp = sbs.m_ranked_points[i]; if (rp.rank == 0 || rp.direction == sort_by_side::dir_from) { continue; } - turn_operation_type const& op = operation_from_rank(rp); + auto const& out_op = operation_from_rank(rp); - if (op.operation != target_operation - && op.operation != operation_continue) + if (out_op.operation != target_operation + && out_op.operation != operation_continue) { continue; } - if (op.enriched.region_id == incoming_op.enriched.region_id - || (skip_isolated && ! op.enriched.isolated)) + if (in_op.enriched.region_id == out_op.enriched.region_id + || (is_intersection && ! out_op.enriched.isolated)) { // Region corresponds to incoming region, or (for intersection) // there is a non-isolated other region which should be taken @@ -660,7 +661,7 @@ public : int& op_index, sbs_type const& sbs, signed_size_type start_turn_index, int start_op_index) const { - sort_by_side::rank_type const selected_rank = select_rank(sbs, false); + sort_by_side::rank_type const selected_rank = select_rank(sbs); int current_priority = 0; for (std::size_t i = 1; i < sbs.m_ranked_points.size(); i++) @@ -688,49 +689,59 @@ public : inline bool analyze_cluster_intersection(signed_size_type& turn_index, int& op_index, sbs_type const& sbs) const { - sort_by_side::rank_type const selected_rank = select_rank(sbs, true); + // Select the rank based on regions and isolation + sort_by_side::rank_type const selected_rank = select_rank(sbs); - if (selected_rank > 0) + if (selected_rank <= 0) { - typename turn_operation_type::comparable_distance_type - min_remaining_distance = 0; + return false; + } - std::size_t selected_index = sbs.m_ranked_points.size(); - for (std::size_t i = 0; i < sbs.m_ranked_points.size(); i++) + // From these ranks, select the index: the first, or the one with + // the smallest remaining distance + typename turn_operation_type::comparable_distance_type + min_remaining_distance = 0; + + std::size_t selected_index = sbs.m_ranked_points.size(); + for (std::size_t i = 0; i < sbs.m_ranked_points.size(); i++) + { + auto const& ranked_point = sbs.m_ranked_points[i]; + + if (ranked_point.rank > selected_rank) { - typename sbs_type::rp const& ranked_point = sbs.m_ranked_points[i]; - - if (ranked_point.rank == selected_rank) - { - turn_operation_type const& op = operation_from_rank(ranked_point); - - if (op.visited.finalized()) - { - // This direction is already traveled before, the same - // cannot be traveled again - continue; - } - - // Take turn with the smallest remaining distance - if (selected_index == sbs.m_ranked_points.size() - || op.remaining_distance < min_remaining_distance) - { - selected_index = i; - min_remaining_distance = op.remaining_distance; - } - } + break; } - - if (selected_index < sbs.m_ranked_points.size()) + else if (ranked_point.rank == selected_rank) { - typename sbs_type::rp const& ranked_point = sbs.m_ranked_points[selected_index]; - turn_index = ranked_point.turn_index; - op_index = ranked_point.operation_index; - return true; + auto const& op = operation_from_rank(ranked_point); + + if (op.visited.finalized()) + { + // This direction is already traveled, + // it cannot be traveled again + continue; + } + + if (selected_index == sbs.m_ranked_points.size() + || op.remaining_distance < min_remaining_distance) + { + // It was unassigned or it is better + selected_index = i; + min_remaining_distance = op.remaining_distance; + } } } - return false; + if (selected_index == sbs.m_ranked_points.size()) + { + // Should not happen, there must be points with the selected rank + return false; + } + + auto const& ranked_point = sbs.m_ranked_points[selected_index]; + turn_index = ranked_point.turn_index; + op_index = ranked_point.operation_index; + return true; } inline bool fill_sbs(sbs_type& sbs, @@ -819,6 +830,7 @@ public : return result; } + // Analyzes a non-clustered "ii" intersection, as if it is clustered. inline bool analyze_ii_intersection(signed_size_type& turn_index, int& op_index, turn_type const& current_turn, segment_identifier const& previous_seg_id) 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 ad248826d..ae2e7b5c8 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp @@ -89,7 +89,6 @@ struct traversal_switch_detector enum isolation_type { - isolation_unknown = -1, isolation_no = 0, isolation_yes = 1, isolation_multiple = 2 @@ -121,7 +120,7 @@ struct traversal_switch_detector struct region_properties { signed_size_type region_id = -1; - isolation_type isolated = isolation_unknown; + isolation_type isolated = isolation_no; set_type unique_turn_ids; connection_map connected_region_counts; }; @@ -374,7 +373,7 @@ struct traversal_switch_detector { region_properties& properties = key_val.second; - if (properties.isolated == isolation_unknown + if (properties.isolated == isolation_no && has_only_isolated_children(properties)) { properties.isolated = isolation_yes; @@ -388,13 +387,36 @@ struct traversal_switch_detector { for (turn_type& turn : m_turns) { + // For difference, for the input walked through in reverse, + // the meaning is reversed: what is isolated is actually not, + // and vice versa. + bool const reverseMeaningInTurn + = (Reverse1 || Reverse2) + && ! turn.is_self() + && ! turn.is_clustered() + && uu_or_ii(turn) + && turn.operations[0].enriched.region_id + != turn.operations[1].enriched.region_id; + for (auto& op : turn.operations) { auto mit = m_connected_regions.find(op.enriched.region_id); if (mit != m_connected_regions.end()) { + bool const reverseMeaningInOp + = reverseMeaningInTurn + && ((op.seg_id.source_index == 0 && Reverse1) + || (op.seg_id.source_index == 1 && Reverse2)); + + // It is assigned to isolated if it's property is "Yes", + // (one connected interior, or chained). + // "Multiple" doesn't count for isolation, + // neither for intersection, neither for difference. region_properties const& prop = mit->second; - op.enriched.isolated = prop.isolated == isolation_yes; + op.enriched.isolated + = reverseMeaningInOp + ? prop.isolated == isolation_no + : prop.isolated == isolation_yes; } } } @@ -478,8 +500,12 @@ struct traversal_switch_detector // Discarded turns don't connect rings to the same region // Also xx are not relevant // (otherwise discarded colocated uu turn could make a connection) - return ! turn.discarded - && ! turn.both(operation_blocked); + return ! turn.discarded && ! turn.both(operation_blocked); + } + + inline bool uu_or_ii(turn_type const& turn) const + { + return turn.both(operation_union) || turn.both(operation_intersection); } inline bool connects_same_region(turn_type const& turn) const @@ -492,7 +518,7 @@ struct traversal_switch_detector if (! turn.is_clustered()) { // If it is a uu/ii-turn (non clustered), it is never same region - return ! (turn.both(operation_union) || turn.both(operation_intersection)); + return ! uu_or_ii(turn); } if (BOOST_GEOMETRY_CONDITION(target_operation == operation_union)) @@ -568,7 +594,10 @@ struct traversal_switch_detector void iterate() { #if defined(BOOST_GEOMETRY_DEBUG_TRAVERSAL_SWITCH_DETECTOR) - std::cout << "BEGIN SWITCH DETECTOR (region_ids and isolation)" << std::endl; + std::cout << "BEGIN SWITCH DETECTOR (region_ids and isolation)" + << (Reverse1 ? " REVERSE_1" : "") + << (Reverse2 ? " REVERSE_2" : "") + << std::endl; #endif // Collect turns per ring @@ -613,14 +642,14 @@ struct traversal_switch_detector { turn_type const& turn = m_turns[turn_index]; - if ((turn.both(operation_union) || turn.both(operation_intersection)) - && ! turn.is_clustered()) + if (uu_or_ii(turn) && ! turn.is_clustered()) { std::cout << (turn.both(operation_union) ? "UU" : "II") << " " << turn_index << " (" << geometry::get<0>(turn.point) << ", " << geometry::get<1>(turn.point) << ")" << " -> " << std::boolalpha + << " [" << turn.operations[0].seg_id.source_index << "/" << turn.operations[1].seg_id.source_index << "] " << "(" << turn.operations[0].enriched.region_id << " " << turn.operations[0].enriched.isolated << ") / (" << turn.operations[1].enriched.region_id diff --git a/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp b/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp index 7dcbf4c8e..08cb516cf 100644 --- a/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp @@ -138,6 +138,11 @@ struct turn_info { return cluster_id > 0; } + inline bool is_self() const + { + return operations[0].seg_id.source_index + == operations[1].seg_id.source_index; + } private : inline bool has12(operation_type type1, operation_type type2) const diff --git a/test/algorithms/set_operations/difference/difference_multi.cpp b/test/algorithms/set_operations/difference/difference_multi.cpp index af45b0d4f..a4efdad25 100644 --- a/test/algorithms/set_operations/difference/difference_multi.cpp +++ b/test/algorithms/set_operations/difference/difference_multi.cpp @@ -204,10 +204,8 @@ void test_areal() #endif } -#if defined(BOOST_GEOMETRY_TEST_FAILURES) - // Generates a polygon with two interiors, i/o a multipoly with 3 rings - TEST_DIFFERENCE(issue_869_a, 3, 3600, 0, 0, 1); -#endif + // Requires reveral of isolation in ii turns. There should be 3 rings. + TEST_DIFFERENCE(issue_869_a, 3, 3600, 0, 0, 3); TEST_DIFFERENCE(issue_888_34, 22, 0.2506824, 6, 0.0253798, 28); TEST_DIFFERENCE(issue_888_37, 15, 0.0451408, 65, 0.3014843, 80); diff --git a/test/algorithms/set_operations/difference/test_difference.hpp b/test/algorithms/set_operations/difference/test_difference.hpp index 0c01d94cb..6c93acb2a 100644 --- a/test/algorithms/set_operations/difference/test_difference.hpp +++ b/test/algorithms/set_operations/difference/test_difference.hpp @@ -327,11 +327,14 @@ std::string test_one(std::string const& caseid, bg::correct(g1); bg::correct(g2); - std::string result = test_difference(caseid + "_a", g1, g2, + std::string result; + +#if ! defined(BOOST_GEOMETRY_TEST_DIFFERENCE_ONLY_B) + result = test_difference(caseid + "_a", g1, g2, expected_count1, expected_rings_count1, expected_point_count1, expected_area1, false, settings); - -#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE +#endif +#if defined(BOOST_GEOMETRY_TEST_DIFFERENCE_ONLY_A) return result; #endif @@ -339,6 +342,10 @@ std::string test_one(std::string const& caseid, expected_count2, expected_rings_count2, expected_point_count2, expected_area2, false, settings); +#if defined(BOOST_GEOMETRY_TEST_DIFFERENCE_ONLY_B) + return result; +#endif + #if ! defined(BOOST_GEOMETRY_TEST_ALWAYS_CHECK_SYMDIFFERENCE) if (settings.sym_difference) #endif From 7f1e294a61c6989ba12f1fa161bfd4c36af8314f Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 14 Jul 2021 13:52:37 +0200 Subject: [PATCH 15/74] [traverse] avoid using isolated for originally non-isolated regions --- .../overlay/traversal_switch_detector.hpp | 100 +++++++++++++----- 1 file changed, 72 insertions(+), 28 deletions(-) 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 ae2e7b5c8..be0f2bcd8 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp @@ -415,7 +415,7 @@ struct traversal_switch_detector region_properties const& prop = mit->second; op.enriched.isolated = reverseMeaningInOp - ? prop.isolated == isolation_no + ? false : prop.isolated == isolation_yes; } } @@ -591,6 +591,76 @@ struct traversal_switch_detector } } +#if defined(BOOST_GEOMETRY_DEBUG_TRAVERSAL_SWITCH_DETECTOR) + void debug_show_results() + { + auto isolation_to_string = [](isolation_type const& iso) -> std::string + { + switch(iso) + { + case isolation_no : return "no"; + case isolation_yes : return "yes"; + case isolation_multiple : return "multiple"; + } + return "error"; + }; + auto set_to_string = [](auto const& s) -> std::string + { + std::ostringstream result; + for (auto item : s) { result << " " << item; } + return result.str(); + }; + + for (auto const& kv : m_connected_regions) + { + auto const& prop = kv.second; + + std::ostringstream sub; + sub << "[turns" << set_to_string(prop.unique_turn_ids) + << "] regions"; + for (auto const& kvs : prop.connected_region_counts) + { + sub << " { " << kvs.first + << " : via [" << set_to_string(kvs.second.unique_turn_ids) + << " ] }"; + } + + std::cout << "REGION " << prop.region_id + << " " << isolation_to_string(prop.isolated) + << " " << sub.str() + << std::endl; + } + + for (std::size_t turn_index = 0; turn_index < m_turns.size(); ++turn_index) + { + turn_type const& turn = m_turns[turn_index]; + + if (uu_or_ii(turn) && ! turn.is_clustered()) + { + std::cout << (turn.both(operation_union) ? "UU" : "II") + << " " << turn_index + << " (" << geometry::get<0>(turn.point) + << ", " << geometry::get<1>(turn.point) << ")" + << " -> " << std::boolalpha + << " [" << turn.operations[0].seg_id.source_index + << "/" << turn.operations[1].seg_id.source_index << "] " + << "(" << turn.operations[0].enriched.region_id + << " " << turn.operations[0].enriched.isolated + << ") / (" << turn.operations[1].enriched.region_id + << " " << turn.operations[1].enriched.isolated << ")" + << std::endl; + } + } + + for (auto const& key_val : m_clusters) + { + cluster_info const& cinfo = key_val.second; + std::cout << "CL RESULT " << key_val.first + << " -> " << cinfo.open_count << std::endl; + } + } +#endif + void iterate() { #if defined(BOOST_GEOMETRY_DEBUG_TRAVERSAL_SWITCH_DETECTOR) @@ -637,33 +707,7 @@ struct traversal_switch_detector #if defined(BOOST_GEOMETRY_DEBUG_TRAVERSAL_SWITCH_DETECTOR) std::cout << "END SWITCH DETECTOR" << std::endl; - - for (std::size_t turn_index = 0; turn_index < m_turns.size(); ++turn_index) - { - turn_type const& turn = m_turns[turn_index]; - - if (uu_or_ii(turn) && ! turn.is_clustered()) - { - std::cout << (turn.both(operation_union) ? "UU" : "II") - << " " << turn_index - << " (" << geometry::get<0>(turn.point) - << ", " << geometry::get<1>(turn.point) << ")" - << " -> " << std::boolalpha - << " [" << turn.operations[0].seg_id.source_index << "/" << turn.operations[1].seg_id.source_index << "] " - << "(" << turn.operations[0].enriched.region_id - << " " << turn.operations[0].enriched.isolated - << ") / (" << turn.operations[1].enriched.region_id - << " " << turn.operations[1].enriched.isolated << ")" - << std::endl; - } - } - - for (auto const& key_val : m_clusters) - { - cluster_info const& cinfo = key_val.second; - std::cout << "CL RESULT " << key_val.first - << " -> " << cinfo.open_count << std::endl; - } + debug_show_results(); #endif } From 42edbd30f246fff720a271c2c9f8e45df0156414 Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 21 Jul 2021 12:32:41 +0200 Subject: [PATCH 16/74] [test] add testcase for issue #888 polygon 53 --- test/algorithms/overlay/multi_overlay_cases.hpp | 6 ++++++ .../set_operations/difference/difference_multi.cpp | 13 +++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/test/algorithms/overlay/multi_overlay_cases.hpp b/test/algorithms/overlay/multi_overlay_cases.hpp index 21753cba9..3b1e4c342 100644 --- a/test/algorithms/overlay/multi_overlay_cases.hpp +++ b/test/algorithms/overlay/multi_overlay_cases.hpp @@ -1534,6 +1534,12 @@ static std::string issue_888_37[2] = "MULTIPOLYGON(((0.594132 0.714429,0.606487 0.701251,0.594811 0.691349,0.594132 0.714429)),((0.663637 0.851798,0.60596 0.926301,0.651077 0.91496,0.663637 0.851798)),((0.550593 0.255888,0.603476 0.274731,0.684151 0.208773,0.625869 0.119956,0.523067 0.0866194,0.476025 0.144909,0.550593 0.255888)),((0.550593 0.255888,0.452782 0.221035,0.459249 0.333709,0.441865 0.351136,0.370548 0.331001,0.315687 0.454629,0.207309 0.362716,0.174164 0.39187,0.173365 0.391061,0.173401 0.392541,0.11983 0.439661,0.177364 0.555306,0.177972 0.580239,0.0906064 0.618386,0.127028 0.663916,0.0564116 0.721999,0.127196 0.664127,0.181673 0.732227,0.182236 0.755361,0.188638 0.740934,0.199131 0.754051,0.261029 0.691392,0.320648 0.715618,0.224866 0.786223,0.382462 0.983231,0.466763 0.85994,0.47812 0.838165,0.39515 0.926659,0.476824 0.77908,0.50332 0.789847,0.525393 0.747525,0.505459 0.72734,0.547556 0.651273,0.482633 0.596213,0.577247 0.52647,0.570444 0.520834,0.600941 0.483052,0.603549 0.394417,0.517116 0.432156,0.563288 0.385417,0.492528 0.36544,0.577515 0.295956,0.550593 0.255888),(0.366654 0.497853,0.305289 0.524648,0.301942 0.521258,0.348942 0.482832,0.366654 0.497853),(0.287131 0.506261,0.291026 0.510204,0.279648 0.535844,0.289209 0.531669,0.277112 0.541559,0.226862 0.654796,0.201344 0.603505,0.178983 0.621787,0.178814 0.61485,0.197613 0.596005,0.187664 0.576007,0.240627 0.552881,0.287131 0.506261),(0.315687 0.454629,0.328117 0.465171,0.297299 0.496067,0.315687 0.454629)),((0.50332 0.789847,0.47812 0.838165,0.517876 0.795762,0.50332 0.789847)),((0.476025 0.144909,0.468192 0.133251,0.448726 0.150373,0.450246 0.176853,0.476025 0.144909)),((0.521709 0.086179,0.399861 0.0466657,0.304173 0.168082,0.392721 0.199633,0.448726 0.150373,0.445833 0.0999749,0.468192 0.133251,0.521709 0.086179)),((0.521709 0.086179,0.523067 0.0866194,0.527613 0.0809854,0.521709 0.086179)),((0.577515 0.295956,0.605233 0.337207,0.607034 0.275999,0.603476 0.274731,0.577515 0.295956)),((0.304173 0.168082,0.296274 0.165267,0.207506 0.246917,0.236386 0.254095,0.304173 0.168082)),((0.392721 0.199633,0.310001 0.272391,0.387958 0.291767,0.423911 0.210747,0.392721 0.199633)),((0.108341 0.416568,0.0230624 0.524775,0.11983 0.439661,0.108341 0.416568)),((0.108341 0.416568,0.135246 0.382428,0.0977468 0.395274,0.108341 0.416568)),((0.668916 0.431986,0.729259 0.521793,0.766538 0.334324,0.788997 0.368549,0.791284 0.312445,0.76895 0.322197,0.778422 0.274563,0.719425 0.179933,0.684151 0.208773,0.76089 0.325716,0.717162 0.344809,0.668916 0.431986)),((0.668916 0.431986,0.656761 0.413896,0.600941 0.483052,0.60016 0.509579,0.643761 0.47744,0.668916 0.431986)),((0.603549 0.394417,0.634572 0.380871,0.605233 0.337207,0.603549 0.394417)),((0.625869 0.119956,0.696266 0.142785,0.611653 0.00706631,0.573697 0.0404517,0.625869 0.119956)),((0.656761 0.413896,0.710003 0.347935,0.634572 0.380871,0.656761 0.413896)),((0.696266 0.142785,0.719425 0.179933,0.745381 0.158712,0.696266 0.142785)),((0.701609 0.660841,0.710619 0.636962,0.70696 0.633931,0.701609 0.660841)),((0.701609 0.660841,0.666999 0.75257,0.681007 0.764449,0.701609 0.660841)),((0.788997 0.368549,0.783115 0.512864,0.842285 0.449754,0.788997 0.368549)),((0.959288 0.239088,0.799738 0.308754,0.992212 0.617482,0.959288 0.239088)),((0.959288 0.239088,0.973756 0.232771,0.958302 0.22776,0.959288 0.239088)),((0.717162 0.344809,0.727272 0.326541,0.710003 0.347935,0.717162 0.344809)),((0.783115 0.512864,0.751874 0.546184,0.780115 0.586441,0.783115 0.512864)),((0.745381 0.158712,0.958302 0.22776,0.938553 0.000778765,0.745381 0.158712)),((0.799738 0.308754,0.791944 0.296253,0.791284 0.312445,0.799738 0.308754)),((0.74515 0.545443,0.729259 0.521793,0.717016 0.583363,0.740154 0.558685,0.74515 0.545443)),((0.74515 0.545443,0.748247 0.550053,0.751874 0.546184,0.74732 0.539692,0.74515 0.545443)),((0.310001 0.272391,0.236386 0.254095,0.211225 0.286021,0.27427 0.30382,0.310001 0.272391)),((0.323855 0.317819,0.370548 0.331001,0.385816 0.296593,0.323855 0.317819)),((0.323855 0.317819,0.27427 0.30382,0.216572 0.354569,0.323855 0.317819)),((0.387958 0.291767,0.385816 0.296593,0.394882 0.293488,0.387958 0.291767)),((0.175851 0.276034,0.14191 0.307253,0.173427 0.333981,0.211225 0.286021,0.175851 0.276034)),((0.175851 0.276034,0.207506 0.246917,0.0140798 0.198842,0.069792 0.24609,0.175851 0.276034)),((0.173427 0.333981,0.135246 0.382428,0.203132 0.359173,0.173427 0.333981)),((0.203132 0.359173,0.207309 0.362716,0.216572 0.354569,0.203132 0.359173)),((0.069792 0.24609,0.0159663 0.230894,0.0815688 0.362756,0.14191 0.307253,0.069792 0.24609)),((0.0815688 0.362756,0.0156364 0.423401,0.0977468 0.395274,0.0815688 0.362756)),((0.224866 0.786223,0.199131 0.754051,0.013265 0.942202,0.224866 0.786223)),((0.643761 0.47744,0.604247 0.548838,0.621545 0.563169,0.680308 0.450499,0.643761 0.47744)),((0.604247 0.548838,0.59913 0.544599,0.598711 0.558841,0.604247 0.548838)),((0.452782 0.221035,0.450246 0.176853,0.425156 0.207942,0.423911 0.210747,0.452782 0.221035)),((0.547556 0.651273,0.566996 0.667759,0.59721 0.609827,0.598711 0.558841,0.547556 0.651273)))" }; +static std::string issue_888_53[2] = +{ + "MULTIPOLYGON(((0.101361 0.873249,0.301118 0.633252,0.285957 0.592644,0.135028 0.636275,0.344319 0.39052,0.0807768 0.389475,0.101361 0.873249)),((0.101361 0.873249,0.0361477 0.951599,0.103672 0.927553,0.101361 0.873249)),((0.301118 0.633252,0.315174 0.670899,0.33042 0.651962,0.330739 0.654302,0.315658 0.672196,0.323461 0.693095,0.334835 0.684373,0.341221 0.73125,0.338625 0.733712,0.34324 0.746072,0.344189 0.75304,0.324735 0.787732,0.287708 0.782026,0.152761 0.910072,0.226024 0.883982,0.215588 0.892864,0.277228 0.872453,0.241092 0.936893,0.327022 0.855964,0.37797 0.839093,0.425729 0.967012,0.529874 0.788791,0.558286 0.779383,0.556701 0.766224,0.65607 0.730838,0.692351 0.704562,0.697876 0.71595,0.702942 0.714146,0.707042 0.706142,0.711407 0.711132,0.799272 0.679842,0.779237 0.641637,0.833376 0.602428,0.780122 0.563447,0.810992 0.50317,0.757461 0.431674,0.767273 0.423323,0.781644 0.335916,0.749286 0.355358,0.709115 0.319338,0.732915 0.280433,0.713883 0.297463,0.704049 0.313171,0.706561 0.317049,0.703397 0.314212,0.686139 0.341775,0.674939 0.332312,0.670981 0.335853,0.658385 0.328037,0.657071 0.317215,0.623065 0.288482,0.644713 0.261593,0.628117 0.246712,0.6106 0.27795,0.602526 0.271128,0.590314 0.2858,0.571143 0.273905,0.578518 0.250844,0.426472 0.122377,0.364986 0.0297914,0.445637 0.196032,0.26697 0.0851721,0.292758 0.232593,0.387037 0.34036,0.344319 0.39052,0.424949 0.39084,0.282042 0.582159,0.285957 0.592644,0.320962 0.582524,0.324109 0.60563,0.301118 0.633252),(0.526427 0.362556,0.553002 0.330628,0.536289 0.382885,0.526427 0.362556),(0.510405 0.381806,0.511534 0.391183,0.502629 0.391148,0.510405 0.381806),(0.484614 0.50262,0.503361 0.485845,0.487873 0.534273,0.4628 0.541521,0.484614 0.50262),(0.632981 0.455744,0.625653 0.461363,0.632188 0.455163,0.632981 0.455744),(0.521031 0.470034,0.521942 0.477601,0.515424 0.475051,0.521031 0.470034),(0.664289 0.376674,0.665904 0.389973,0.664792 0.391791,0.654849 0.391752,0.664289 0.376674),(0.716114 0.391995,0.698833 0.391926,0.716805 0.374873,0.721777 0.371886,0.731559 0.380151,0.716114 0.391995),(0.476049 0.442104,0.497 0.445061,0.488199 0.455992,0.476049 0.442104),(0.417634 0.770625,0.48428 0.664179,0.524665 0.629807,0.541078 0.636494,0.54301 0.652544,0.417634 0.770625),(0.417634 0.770625,0.406699 0.78809,0.409979 0.777834,0.417634 0.770625),(0.562537 0.36366,0.602098 0.293112,0.613594 0.300245,0.562537 0.36366),(0.590531 0.494689,0.590473 0.49457,0.597976 0.482587,0.58827 0.49003,0.57156 0.455585,0.611365 0.461203,0.620502 0.446609,0.62793 0.452047,0.621457 0.462628,0.623608 0.462931,0.619207 0.466306,0.617496 0.469103,0.62395 0.462979,0.647385 0.466287,0.677877 0.488607,0.679066 0.498397,0.6847 0.493601,0.697077 0.50266,0.682592 0.527448,0.684251 0.541111,0.676403 0.53804,0.640975 0.598666,0.617678 0.550644,0.646318 0.526268,0.59637 0.506724,0.594746 0.503377,0.590761 0.504529,0.585522 0.502479,0.590205 0.494998,0.590531 0.494689),(0.544962 0.391316,0.54201 0.389156,0.562537 0.36366,0.547024 0.391324,0.608717 0.391569,0.580186 0.417099,0.546427 0.392389,0.543464 0.397674,0.561152 0.434132,0.541862 0.451393,0.518387 0.44808,0.517823 0.443399,0.515759 0.44708,0.51758 0.441384,0.515288 0.422347,0.529192 0.405077,0.533607 0.391271,0.540286 0.391297,0.540339 0.391232,0.540371 0.391298,0.544962 0.391316)),((0.152761 0.910072,0.103672 0.927553,0.104862 0.955521,0.152761 0.910072)),((0.590531 0.494689,0.594746 0.503377,0.596912 0.502751,0.617496 0.469103,0.590531 0.494689)),((0.645636 0.223015,0.645246 0.219802,0.644295 0.220945,0.645636 0.223015)),((0.645636 0.223015,0.649585 0.255543,0.644713 0.261593,0.651004 0.267233,0.657071 0.317215,0.674939 0.332312,0.699286 0.310525,0.703397 0.314212,0.704049 0.313171,0.701216 0.308798,0.713883 0.297463,0.756461 0.22946,0.79194 0.273302,0.808697 0.171384,0.794671 0.168431,0.81435 0.137,0.832141 0.0287975,0.730585 0.154935,0.462894 0.0985647,0.590598 0.213071,0.578518 0.250844,0.602526 0.271128,0.6251 0.244006,0.628117 0.246712,0.638996 0.227311,0.644295 0.220945,0.643368 0.219514,0.644883 0.216813,0.645246 0.219802,0.697673 0.156814,0.713413 0.176264,0.659074 0.243756,0.645636 0.223015)),((0.544962 0.391316,0.546427 0.392389,0.547024 0.391324,0.544962 0.391316)),((0.543464 0.397674,0.540371 0.391298,0.540286 0.391297,0.529192 0.405077,0.51758 0.441384,0.517823 0.443399,0.543464 0.397674)),((0.900875 0.327668,0.810992 0.50317,0.86705 0.57804,0.942565 0.52335,0.900875 0.327668)),((0.900875 0.327668,0.947768 0.236106,0.888903 0.271473,0.900875 0.327668)),((0.808697 0.171384,0.824352 0.174681,0.840911 0.300307,0.888903 0.271473,0.848599 0.0822989,0.81435 0.137,0.808697 0.171384)),((0.840911 0.300307,0.822665 0.31127,0.846188 0.340338,0.840911 0.300307)),((0.79194 0.273302,0.781644 0.335916,0.822665 0.31127,0.79194 0.273302)),((0.86705 0.57804,0.833376 0.602428,0.948285 0.686538,0.86705 0.57804)))", + "MULTIPOLYGON(((0.659074 0.243756,0.649585 0.255543,0.651004 0.267233,0.699286 0.310525,0.701216 0.308798,0.659074 0.243756)),((0.65607 0.730838,0.614949 0.760619,0.558286 0.779383,0.569893 0.875763,0.926464 0.956953,0.711407 0.711132,0.702942 0.714146,0.699891 0.720104,0.697876 0.71595,0.65607 0.730838)),((0.6251 0.244006,0.638996 0.227311,0.643368 0.219514,0.606658 0.162855,0.590598 0.213071,0.6251 0.244006)),((0.338625 0.733712,0.323461 0.693095,0.220913 0.771732,0.287708 0.782026,0.338625 0.733712)),((0.315174 0.670899,0.28149 0.712736,0.315658 0.672196,0.315174 0.670899)),((0.625653 0.461363,0.623608 0.462931,0.62395 0.462979,0.625653 0.461363)),((0.794671 0.168431,0.730585 0.154935,0.713413 0.176264,0.756461 0.22946,0.794671 0.168431)),((0.597976 0.482587,0.619207 0.466306,0.621457 0.462628,0.611365 0.461203,0.597976 0.482587)),((0.679066 0.498397,0.646318 0.526268,0.676403 0.53804,0.682592 0.527448,0.679066 0.498397)),((0.402869 0.800065,0.401491 0.804374,0.540911 0.757512,0.402869 0.800065)),((0.402869 0.800065,0.406699 0.78809,0.398324 0.801466,0.402869 0.800065)),((0.719855 0.46368,0.757461 0.431674,0.746845 0.417494,0.719855 0.46368)),((0.719855 0.46368,0.696391 0.483651,0.701969 0.494288,0.719855 0.46368)),((0.746845 0.417494,0.77151 0.375285,0.749286 0.355358,0.736399 0.363101,0.750855 0.385413,0.725474 0.369665,0.721777 0.371886,0.701659 0.354888,0.691299 0.34846,0.665904 0.389973,0.666125 0.391796,0.698833 0.391926,0.669517 0.419742,0.670404 0.427047,0.716114 0.391995,0.727787 0.392041,0.746845 0.417494)),((0.708595 0.320188,0.709115 0.319338,0.706561 0.317049,0.708595 0.320188)),((0.708595 0.320188,0.692237 0.346927,0.701659 0.354888,0.725474 0.369665,0.736399 0.363101,0.708595 0.320188)),((0.473998 0.577658,0.465083 0.605533,0.471121 0.607993,0.530823 0.551344,0.52892 0.535542,0.473998 0.577658)),((0.473998 0.577658,0.487873 0.534273,0.527391 0.522848,0.524311 0.49727,0.509505 0.480347,0.503361 0.485845,0.506294 0.476676,0.501948 0.471709,0.484614 0.50262,0.430805 0.55077,0.4628 0.541521,0.434005 0.592872,0.447166 0.598234,0.473998 0.577658)),((0.509505 0.480347,0.515424 0.475051,0.507771 0.472056,0.506294 0.476676,0.509505 0.480347)),((0.502836 0.470125,0.507771 0.472056,0.515566 0.447682,0.515432 0.447663,0.502836 0.470125)),((0.502836 0.470125,0.499379 0.468772,0.501948 0.471709,0.502836 0.470125)),((0.502031 0.312271,0.526427 0.362556,0.518569 0.371997,0.535749 0.384573,0.533607 0.391271,0.511534 0.391183,0.515288 0.422347,0.497 0.445061,0.515432 0.447663,0.515759 0.44708,0.515566 0.447682,0.518387 0.44808,0.521031 0.470034,0.541862 0.451393,0.57156 0.455585,0.561152 0.434132,0.580186 0.417099,0.620502 0.446609,0.654849 0.391752,0.608717 0.391569,0.660475 0.345254,0.658385 0.328037,0.613594 0.300245,0.623065 0.288482,0.6106 0.27795,0.602098 0.293112,0.590314 0.2858,0.553002 0.330628,0.571143 0.273905,0.445637 0.196032,0.494788 0.297342,0.499477 0.291064,0.502031 0.312271),(0.537856 0.386115,0.535749 0.384573,0.536289 0.382885,0.537856 0.386115),(0.537856 0.386115,0.54201 0.389156,0.540339 0.391232,0.537856 0.386115)),((0.502031 0.312271,0.494788 0.297342,0.467142 0.334354,0.50832 0.364495,0.502031 0.312271)),((0.50832 0.364495,0.510405 0.381806,0.518569 0.371997,0.50832 0.364495)),((0.509635 0.623684,0.524665 0.629807,0.538821 0.617759,0.534711 0.583632,0.509635 0.623684)),((0.509635 0.623684,0.471121 0.607993,0.461323 0.617289,0.432133 0.708562,0.48428 0.664179,0.509635 0.623684)),((0.465083 0.605533,0.447166 0.598234,0.418801 0.619985,0.373678 0.700452,0.461323 0.617289,0.465083 0.605533)),((0.374931 0.830954,0.37797 0.839093,0.529874 0.788791,0.539477 0.772358,0.374931 0.830954)),((0.374931 0.830954,0.369376 0.816075,0.340592 0.843183,0.374931 0.830954)),((0.524311 0.49727,0.542793 0.518396,0.556414 0.514458,0.576592 0.498985,0.521942 0.477601,0.524311 0.49727)),((0.530823 0.551344,0.534711 0.583632,0.561889 0.540224,0.553113 0.530193,0.530823 0.551344)),((0.527391 0.522848,0.52892 0.535542,0.5462 0.522291,0.542793 0.518396,0.527391 0.522848)),((0.539477 0.772358,0.556701 0.766224,0.55437 0.746871,0.539477 0.772358)),((0.483053 0.462384,0.453094 0.450661,0.359867 0.562668,0.372228 0.567704,0.406154 0.557896,0.483053 0.462384)),((0.483053 0.462384,0.499379 0.468772,0.488199 0.455992,0.483053 0.462384)),((0.430805 0.55077,0.406154 0.557896,0.391829 0.575689,0.399476 0.578805,0.430805 0.55077)),((0.359867 0.562668,0.315812 0.54472,0.320962 0.582524,0.350431 0.574005,0.359867 0.562668)),((0.467142 0.334354,0.420948 0.300541,0.387037 0.34036,0.427828 0.386985,0.467142 0.334354)),((0.431222 0.390865,0.467936 0.43283,0.502629 0.391148,0.431222 0.390865)),((0.431222 0.390865,0.427828 0.386985,0.424949 0.39084,0.431222 0.390865)),((0.467936 0.43283,0.461881 0.440105,0.476049 0.442104,0.467936 0.43283)),((0.453094 0.450661,0.461881 0.440105,0.405934 0.432208,0.453094 0.450661)),((0.340592 0.843183,0.281925 0.864075,0.277228 0.872453,0.327022 0.855964,0.340592 0.843183)),((0.350431 0.574005,0.324109 0.60563,0.33042 0.651962,0.391829 0.575689,0.372228 0.567704,0.350431 0.574005)),((0.354048 0.77502,0.369376 0.816075,0.409979 0.777834,0.432133 0.708562,0.354048 0.77502)),((0.354048 0.77502,0.345181 0.751271,0.344189 0.75304,0.347896 0.780256,0.354048 0.77502)),((0.434005 0.592872,0.399476 0.578805,0.378706 0.59739,0.330739 0.654302,0.334835 0.684373,0.418801 0.619985,0.434005 0.592872)),((0.373678 0.700452,0.341221 0.73125,0.34324 0.746072,0.345181 0.751271,0.373678 0.700452)),((0.281925 0.864075,0.311609 0.81114,0.226024 0.883982,0.281925 0.864075)),((0.311609 0.81114,0.336908 0.789608,0.324735 0.787732,0.311609 0.81114)),((0.347896 0.780256,0.336908 0.789608,0.349433 0.791538,0.347896 0.780256)),((0.712142 0.513687,0.759426 0.603857,0.780122 0.563447,0.712142 0.513687)),((0.712142 0.513687,0.701969 0.494288,0.697077 0.50266,0.712142 0.513687)),((0.582796 0.506832,0.561889 0.540224,0.590925 0.573414,0.617678 0.550644,0.59637 0.506724,0.590761 0.504529,0.582796 0.506832)),((0.582796 0.506832,0.585522 0.502479,0.583256 0.501592,0.575516 0.508936,0.582796 0.506832)),((0.575516 0.508936,0.556414 0.514458,0.5462 0.522291,0.553113 0.530193,0.575516 0.508936)),((0.759426 0.603857,0.716989 0.686719,0.779237 0.641637,0.759426 0.603857)),((0.675652 0.470277,0.670404 0.427047,0.632981 0.455744,0.647385 0.466287,0.675652 0.470277)),((0.675652 0.470277,0.677877 0.488607,0.6847 0.493601,0.696391 0.483651,0.690475 0.472369,0.675652 0.470277)),((0.669517 0.419742,0.666125 0.391796,0.664792 0.391791,0.62793 0.452047,0.632188 0.455163,0.669517 0.419742)),((0.660475 0.345254,0.664289 0.376674,0.684569 0.344284,0.670981 0.335853,0.660475 0.345254)),((0.576592 0.498985,0.583256 0.501592,0.590205 0.494998,0.590473 0.49457,0.58827 0.49003,0.576592 0.498985)),((0.692237 0.346927,0.686139 0.341775,0.684569 0.344284,0.691299 0.34846,0.692237 0.346927)),((0.675782 0.67041,0.640975 0.598666,0.629779 0.617826,0.675782 0.67041)),((0.675782 0.67041,0.692351 0.704562,0.700498 0.698662,0.675782 0.67041)),((0.629779 0.617826,0.590925 0.573414,0.538821 0.617759,0.541078 0.636494,0.554323 0.64189,0.54301 0.652544,0.55437 0.746871,0.629779 0.617826)),((0.716989 0.686719,0.700498 0.698662,0.707042 0.706142,0.716989 0.686719)))" +}; + static std::string bug_21155501[2] = { "MULTIPOLYGON(((-8.3935546875 27.449790329784214,4.9658203125 18.729501999072138,11.8212890625 23.563987128451217,9.7119140625 25.48295117535531,9.8876953125 31.728167146023935,8.3056640625 32.99023555965106,8.5693359375 37.16031654673677,-1.8896484375 35.60371874069731,-0.5712890625 32.02670629333614,-8.9208984375 29.458731185355344,-8.3935546875 27.449790329784214)))", diff --git a/test/algorithms/set_operations/difference/difference_multi.cpp b/test/algorithms/set_operations/difference/difference_multi.cpp index a4efdad25..7d7cad485 100644 --- a/test/algorithms/set_operations/difference/difference_multi.cpp +++ b/test/algorithms/set_operations/difference/difference_multi.cpp @@ -204,11 +204,16 @@ void test_areal() #endif } - // Requires reveral of isolation in ii turns. There should be 3 rings. - TEST_DIFFERENCE(issue_869_a, 3, 3600, 0, 0, 3); + // Cases below go (or went) wrong in either a ( [0] - [1] ) or b ( [1] - [0] ) + // Requires reversal of isolation in ii turns. There should be 3 rings. + TEST_DIFFERENCE(issue_869_a, 3, 3600, 0, 0, 3); // a went wrong - TEST_DIFFERENCE(issue_888_34, 22, 0.2506824, 6, 0.0253798, 28); - TEST_DIFFERENCE(issue_888_37, 15, 0.0451408, 65, 0.3014843, 80); + TEST_DIFFERENCE(issue_888_34, 22, 0.2506824, 6, 0.0253798, 28); // a went wrong + TEST_DIFFERENCE(issue_888_37, 15, 0.0451408, 65, 0.3014843, 80); // b went wrong + +#if defined(BOOST_GEOMETRY_TEST_FAILURES) + TEST_DIFFERENCE(issue_888_53, 117, 0.2973268, 17, 0.0525798, 134); // a goes wrong +#endif // Areas and #clips correspond with POSTGIS (except sym case) test_one("case_101_multi", From efff23114a1ed7c87d0b58551ff7e184070c5f84 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 30 Jul 2021 19:06:29 +0200 Subject: [PATCH 17/74] [test] Fix static asserts by passing types. --- test/algorithms/comparable_distance.cpp | 104 ++++++++---------- test/algorithms/distance/distance.cpp | 19 ++-- .../distance/distance_brute_force.hpp | 6 +- test/util/math_sqrt.cpp | 4 +- 4 files changed, 62 insertions(+), 71 deletions(-) diff --git a/test/algorithms/comparable_distance.cpp b/test/algorithms/comparable_distance.cpp index 1df2e6a45..8ecbc57ee 100644 --- a/test/algorithms/comparable_distance.cpp +++ b/test/algorithms/comparable_distance.cpp @@ -184,19 +184,18 @@ struct test_variant_different_default_strategy variant_type v1, v2; + using variant_cdistance_t = typename bg::comparable_distance_result + < + variant_type, variant_type, bg::default_strategy + >::type; + using cdistance_t = typename bg::comparable_distance_result + < + point_type, point_type, bg::default_strategy + >::type; BOOST_GEOMETRY_STATIC_ASSERT( - (std::is_same - < - typename bg::comparable_distance_result - < - variant_type, variant_type, bg::default_strategy - >::type, - typename bg::comparable_distance_result - < - point_type, point_type, bg::default_strategy - >::type - >::value), - "Unexpected result type"); + (std::is_same::value), + "Unexpected result type", + variant_cdistance_t, cdistance_t); // Default strategy v1 = point; @@ -257,27 +256,23 @@ struct test_variant_same_default_strategy variant_type v1, v2; + using variant_cdistance_t = typename bg::comparable_distance_result + < + variant_type, variant_type, bg::default_strategy + >::type; BOOST_GEOMETRY_STATIC_ASSERT( - (std::is_same - < - typename bg::comparable_distance_result - < - variant_type, variant_type, bg::default_strategy - >::type, - ExpectedResultType - >::value), - "Unexpected result type"); + (std::is_same::value), + "Unexpected result type", + variant_cdistance_t, ExpectedResultType); + using cdistance_t = typename bg::comparable_distance_result + < + point_type, point_type, bg::default_strategy + >::type; BOOST_GEOMETRY_STATIC_ASSERT( - (std::is_same - < - typename bg::comparable_distance_result - < - point_type, point_type, bg::default_strategy - >::type, - ExpectedResultType - >::value), - "Unexpected result type"); + (std::is_same::value), + "Unexpected result type", + cdistance_t, ExpectedResultType); // Default strategy v1 = point; @@ -348,27 +343,23 @@ struct test_variant_with_strategy strategy_type strategy; + using variant_cdistance_t = typename bg::comparable_distance_result + < + variant_type, variant_type, strategy_type + >::type; BOOST_GEOMETRY_STATIC_ASSERT( - (std::is_same - < - typename bg::comparable_distance_result - < - variant_type, variant_type, strategy_type - >::type, - ExpectedResultType - >::value), - "Unexpected result type"); + (std::is_same::value), + "Unexpected result type", + variant_cdistance_t, ExpectedResultType); + using cdistance_t = typename bg::comparable_distance_result + < + segment_type, linestring_type, strategy_type + >::type; BOOST_GEOMETRY_STATIC_ASSERT( - (std::is_same - < - typename bg::comparable_distance_result - < - segment_type, linestring_type, strategy_type - >::type, - ExpectedResultType - >::value), - "Unexpected result type"); + (std::is_same::value), + "Unexpected result type", + cdistance_t, ExpectedResultType); // Passed strategy v1 = seg; @@ -462,17 +453,14 @@ struct test_variant_boxes typename bg::util::detail::default_integral::type >::type expected_result_type; + using variant_cdistance_t = typename bg::comparable_distance_result + < + variant_type, variant_type, bg::default_strategy + >::type; BOOST_GEOMETRY_STATIC_ASSERT( - (std::is_same - < - typename bg::comparable_distance_result - < - variant_type, variant_type, bg::default_strategy - >::type, - expected_result_type - >::value), - "Unexpected result type" - ); + (std::is_same::value), + "Unexpected result type", + variant_cdistance_t, expected_result_type); // Default strategy check_result::apply(bg::comparable_distance(v1, v2), diff --git a/test/algorithms/distance/distance.cpp b/test/algorithms/distance/distance.cpp index dbf66afe0..6f1a7b6a4 100644 --- a/test/algorithms/distance/distance.cpp +++ b/test/algorithms/distance/distance.cpp @@ -84,7 +84,8 @@ void test_distance_point() typedef typename services::return_type::type cab_return_type; BOOST_GEOMETRY_STATIC_ASSERT( (std::is_same::type>::value), - "Unexpected result type"); + "Unexpected result type", + cab_return_type, typename bg::coordinate_type

::type); taxicab_distance tcd; cab_return_type d = bg::distance(p1, p2, tcd); @@ -460,16 +461,14 @@ void test_variant() variant_type v1, v2; + using distance_t = typename bg::distance_result + < + variant_type, variant_type, bg::default_strategy + >::type; BOOST_GEOMETRY_STATIC_ASSERT( - (std::is_same - < - typename bg::distance_result - < - variant_type, variant_type, bg::default_strategy - >::type, - double - >::value), - "Unexpected result type"); + (std::is_same::value), + "Unexpected result type", + distance_t, double); // Default strategy v1 = point; diff --git a/test/algorithms/distance/distance_brute_force.hpp b/test/algorithms/distance/distance_brute_force.hpp index 64ad16cd6..7c975cc1f 100644 --- a/test/algorithms/distance/distance_brute_force.hpp +++ b/test/algorithms/distance/distance_brute_force.hpp @@ -59,9 +59,11 @@ struct distance_from_bg Strategy const& strategy) { BOOST_GEOMETRY_STATIC_ASSERT((use_distance_from_bg::value), - "Unexpected kind of Geometry1"); + "Unexpected kind of Geometry1", + Geometry1); BOOST_GEOMETRY_STATIC_ASSERT((use_distance_from_bg::value), - "Unexpected kind of Geometry1"); + "Unexpected kind of Geometry2", + Geometry2); return geometry::distance(geometry1, geometry2, strategy); } diff --git a/test/util/math_sqrt.cpp b/test/util/math_sqrt.cpp index e06bc05af..9e3688b3d 100644 --- a/test/util/math_sqrt.cpp +++ b/test/util/math_sqrt.cpp @@ -64,7 +64,9 @@ template inline void check_sqrt(Argument const& arg, Result const& result) { using return_type = typename bg::math::detail::square_root::return_type; - BOOST_GEOMETRY_STATIC_ASSERT((std::is_same::value), "Wrong return type"); + BOOST_GEOMETRY_STATIC_ASSERT((std::is_same::value), + "Wrong return type", + return_type, Result); #ifdef BOOST_GEOMETRY_TEST_DEBUG std::cout << "testing: " << typeid(Result).name() From 6848b43f97b9c372925f0c2b768d064eeaa8c612 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 19 Jul 2021 15:18:23 +0200 Subject: [PATCH 18/74] [index] Add minmax/maxmin heap algorithms. --- .../geometry/index/detail/maxmin_heap.hpp | 107 ++++ .../geometry/index/detail/minmax_heap.hpp | 489 ++++++++++++++++++ 2 files changed, 596 insertions(+) create mode 100644 include/boost/geometry/index/detail/maxmin_heap.hpp create mode 100644 include/boost/geometry/index/detail/minmax_heap.hpp diff --git a/include/boost/geometry/index/detail/maxmin_heap.hpp b/include/boost/geometry/index/detail/maxmin_heap.hpp new file mode 100644 index 000000000..01ae54ae2 --- /dev/null +++ b/include/boost/geometry/index/detail/maxmin_heap.hpp @@ -0,0 +1,107 @@ +// Boost.Geometry + +// Copyright (c) 2021, 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. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_MAXMIN_HEAP_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_MAXMIN_HEAP_HPP + +#include + +namespace boost { namespace geometry { namespace index { namespace detail +{ + +template +inline void push_maxmin_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + minmax_heap_detail::push_heap(first, last, comp); +} + +template +inline void push_maxmin_heap(It first, It last) +{ + using namespace minmax_heap_detail; + minmax_heap_detail::push_heap(first, last, std::less<>()); +} + +template +inline void pop_top_maxmin_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + pop_heap(first, first, last, comp); +} + +template +inline void pop_top_maxmin_heap(It first, It last) +{ + using namespace minmax_heap_detail; + pop_heap(first, first, last, std::less<>()); +} + +template +inline void pop_bottom_maxmin_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + It bottom = minmax_heap_detail::bottom_heap(first, last, comp); + pop_heap(first, bottom, last, comp); +} + +template +inline void pop_bottom_maxmin_heap(It first, It last) +{ + using namespace minmax_heap_detail; + auto&& comp = std::less<>(); + It bottom = minmax_heap_detail::bottom_heap(first, last, comp); + pop_heap(first, bottom, last, comp); +} + +template +inline void make_maxmin_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + return minmax_heap_detail::make_heap(first, last, comp); +} + +template +inline void make_maxmin_heap(It first, It last) +{ + using namespace minmax_heap_detail; + return minmax_heap_detail::make_heap(first, last, std::less<>()); +} + +template +inline bool is_maxmin_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + return minmax_heap_detail::is_heap(first, last, comp); +} + +template +inline bool is_maxmin_heap(It first, It last) +{ + using namespace minmax_heap_detail; + return minmax_heap_detail::is_heap(first, last, std::less<>()); +} + +template +inline decltype(auto) bottom_maxmin_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + return *minmax_heap_detail::bottom_heap(first, last, comp); +} + +template +inline decltype(auto) bottom_maxmin_heap(It first, It last) +{ + using namespace minmax_heap_detail; + return *minmax_heap_detail::bottom_heap(first, last, std::less<>()); +} + + +}}}} // namespace boost::geometry::index::detail + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_MAXMIN_HEAP_HPP diff --git a/include/boost/geometry/index/detail/minmax_heap.hpp b/include/boost/geometry/index/detail/minmax_heap.hpp new file mode 100644 index 000000000..18b44d918 --- /dev/null +++ b/include/boost/geometry/index/detail/minmax_heap.hpp @@ -0,0 +1,489 @@ +// Boost.Geometry + +// Copyright (c) 2021, 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. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_MINMAX_HEAP_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_MINMAX_HEAP_HPP + +#include +#include +#include + +#ifdef _MSC_VER // msvc and clang-win +#include +#endif + +namespace boost { namespace geometry { namespace index { namespace detail +{ + +// Resources: +// https://en.wikipedia.org/wiki/Min-max_heap +// http://akira.ruc.dk/~keld/teaching/algoritmedesign_f03/Artikler/02/Atkinson86.pdf +// https://probablydance.com/2020/08/31/on-modern-hardware-the-min-max-heap-beats-a-binary-heap/ +// https://stackoverflow.com/questions/6531543/efficient-implementation-of-binary-heaps +// https://stackoverflow.com/questions/994593/how-to-do-an-integer-log2-in-c + +namespace minmax_heap_detail +{ + +template +using bitsize = std::integral_constant; + +template +using diff_t = typename std::iterator_traits::difference_type; +template +using val_t = typename std::iterator_traits::value_type; + +// TODO: In C++20 use std::bit_width() + +template ::value || (bitsize::value != 32 && bitsize::value != 64), int> = 0> +inline int level(T i) +{ + ++i; + int r = 0; + while (i >>= 1) + ++r; + return r; +} + +//template +//inline int level(T i) +//{ +// using std::log2; +// return int(log2(i + 1)); +//} + +#ifdef _MSC_VER // msvc and clang-win + +template ::value && bitsize::value == 32, int> = 0> +inline int level(T i) +{ + unsigned long r = 0; + _BitScanReverse(&r, (unsigned long)(i + 1)); + return int(r); +} + +template ::value && bitsize::value == 64, int> = 0> +inline int level(T i) +{ + unsigned long r = 0; +#ifdef _WIN64 + _BitScanReverse64(&r, (unsigned long long)(i + 1)); +#else + if (_BitScanReverse(&r, (unsigned long)((i + 1) >> 32))) + r += 32; + else + _BitScanReverse(&r, (unsigned long)(i + 1)); +#endif + return int(r); +} + +#elif defined(__clang__) || defined(__GNUC__) +// Only available in gcc-10 and clang-10 +//#elif defined(__has_builtin) && __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll) + +template ::value && bitsize::value == 32, int> = 0> +inline int level(T i) +{ + return 31 - __builtin_clzl((unsigned long)(i + 1)); +} + +template ::value && bitsize::value == 64, int> = 0> +inline int level(T i) +{ + return 63 - __builtin_clzll((unsigned long long)(i + 1)); +} + +#else + +template ::value && bitsize::value == 32, int> = 0> +inline int level(T i) +{ + ++i; + int r = 0; + if (i >= 65536) { r += 16; i >>= 16; } + if (i >= 256) { r += 8; i >>= 8; } + if (i >= 16) { r += 4; i >>= 4; } + if (i >= 4) { r += 2; i >>= 2; } + if (i >= 2) { r += 1; i >>= 1; } + return r; +} + +template ::value && bitsize::value == 64, int> = 0> +inline int level(T i) +{ + ++i; + int r = 0; + if (i >= 4294967296ll) { r += 32; i >>= 32; } + if (i >= 65536ll) { r += 16; i >>= 16; } + if (i >= 256ll) { r += 8; i >>= 8; } + if (i >= 16ll) { r += 4; i >>= 4; } + if (i >= 4ll) { r += 2; i >>= 2; } + if (i >= 2ll) { r += 1; i >>= 1; } + return r; +} + +#endif + + +// min/max functions only differ in the order of arguments in comp +struct min_call +{ + template + bool operator()(Compare&& comp, T1 const& v1, T2 const& v2) const + { + return comp(v1, v2); + } +}; + +struct max_call +{ + template + bool operator()(Compare&& comp, T1 const& v1, T2 const& v2) const + { + return comp(v2, v1); + } +}; + + +template +inline void push_heap2(It first, diff_t c, val_t val, Compare comp) +{ + while (c > 2) + { + diff_t const g = (c - 3) >> 2; // grandparent index + if (! Call()(comp, val, *(first + g))) + break; + *(first + c) = std::move(*(first + g)); + c = g; + } + + *(first + c) = std::move(val); +} + +template +inline void push_heap1(It first, diff_t c, val_t val, Compare comp) +{ + diff_t const p = (c - 1) >> 1; // parent index + if (MinCall()(comp, *(first + p), val)) + { + *(first + c) = std::move(*(first + p)); + return push_heap2(first, p, std::move(val), comp); + } + else + return push_heap2(first, c, std::move(val), comp); +} + +template +inline void push_heap(It first, It last, Compare comp) +{ + diff_t const size = last - first; + if (size < 2) + return; + + diff_t c = size - 1; // back index + val_t val = std::move(*(first + c)); + if (level(c) % 2 == 0) // is min level + push_heap1(first, c, std::move(val), comp); + else + push_heap1(first, c, std::move(val), comp); +} + + +template +inline diff_t pick_grandchild4(It first, diff_t f, Compare comp) +{ + It it = first + f; + diff_t m1 = Call()(comp, *(it), *(it + 1)) ? f : f + 1; + diff_t m2 = Call()(comp, *(it + 2), *(it + 3)) ? f + 2 : f + 3; + return Call()(comp, *(first + m1), *(first + m2)) ? m1 : m2; +} + +//template +//inline diff_t pick_descendant(It first, diff_t f, diff_t l, Compare comp) +//{ +// diff_t m = f; +// for (++f; f != l; ++f) +// if (Call()(comp, *(first + f), *(first + m))) +// m = f; +// return m; +//} + +template +inline void pop_heap1(It first, diff_t p, diff_t size, val_t val, Compare comp) +{ + if (size >= 7) // grandparent of 4 grandchildren is possible + { + diff_t const last_g = (size - 3) >> 2; // grandparent of the element behind back + while (p < last_g) // p is grandparent of 4 grandchildren + { + diff_t const ll = 4 * p + 3; + diff_t const m = pick_grandchild4(first, ll, comp); + + if (! Call()(comp, *(first + m), val)) + break; + + *(first + p) = std::move(*(first + m)); + + diff_t par = (m - 1) >> 1; + if (Call()(comp, *(first + par), val)) + { + using std::swap; + swap(*(first + par), val); + } + + p = m; + } + } + + if (size >= 2 && p <= ((size - 2) >> 1)) // at least one child + { + diff_t const l = 2 * p + 1; + diff_t m = l; // left child + if (size >= 3 && p <= ((size - 3) >> 1)) // at least two children + { + // m = left child + diff_t m2 = l + 1; // right child + if (size >= 4 && p <= ((size - 4) >> 2)) // at least two children and one grandchild + { + diff_t const ll = 2 * l + 1; + m = ll; // left most grandchild + // m2 = right child + if (size >= 5 && p <= ((size - 5) >> 2)) // at least two children and two grandchildren + { + m = Call()(comp, *(first + ll), *(first + ll + 1)) ? ll : (ll + 1); // greater of the left grandchildren + // m2 = right child + if (size >= 6 && p <= ((size - 6) >> 2)) // at least two children and three grandchildren + { + // m = greater of the left grandchildren + m2 = ll + 2; // third grandchild + } + } + } + + m = Call()(comp, *(first + m), *(first + m2)) ? m : m2; + } + + if (Call()(comp, *(first + m), val)) + { + *(first + p) = std::move(*(first + m)); + + if (m >= 3 && p <= ((m - 3) >> 2)) // is p grandparent of m + { + diff_t par = (m - 1) >> 1; + if (Call()(comp, *(first + par), val)) + { + using std::swap; + swap(*(first + par), val); + } + } + + p = m; + } + } + + *(first + p) = std::move(val); +} + +template +inline void pop_heap(It first, It el, It last, Compare comp) +{ + diff_t size = last - first; + if (size < 2) + return; + + --last; + val_t val = std::move(*last); + *last = std::move(*el); + + // Ignore the last element + --size; + + diff_t p = el - first; + if (level(p) % 2 == 0) // is min level + pop_heap1(first, p, size, std::move(val), comp); + else + pop_heap1(first, p, size, std::move(val), comp); +} + +template +inline void make_heap(It first, It last, Compare comp) +{ + diff_t size = last - first; + diff_t p = size / 2; + if (p <= 0) + return; + int level_p = level(p - 1); + diff_t level_f = (diff_t(1) << level_p) - 1; + while (p > 0) + { + --p; + val_t val = std::move(*(first + p)); + if (level_p % 2 == 0) // is min level + pop_heap1(first, p, size, std::move(val), comp); + else + pop_heap1(first, p, size, std::move(val), comp); + if (p == level_f) + { + --level_p; + level_f >>= 1; + } + } +} + +template +inline bool is_heap(It first, It last, Compare comp) +{ + diff_t const size = last - first; + diff_t pow2 = 4; + bool is_min_level = false; + for (diff_t i = 1; i < size; ++i) + { + if (i == pow2 - 1) + { + pow2 *= 2; + is_min_level = ! is_min_level; + } + + diff_t const p = (i - 1) >> 1; + if (is_min_level) + { + if (Call()(comp, *(first + p), *(first + i))) + return false; + } + else + { + if (Call()(comp, *(first + i), *(first + p))) + return false; + } + + if (i >= 3) + { + diff_t const g = (p - 1) >> 1; + if (is_min_level) + { + if (Call()(comp, *(first + i), *(first + g))) + return false; + } + else + { + if (Call()(comp, *(first + g), *(first + i))) + return false; + } + } + } + return true; +} + +template +inline It bottom_heap(It first, It last, Compare comp) +{ + diff_t const size = last - first; + if (size <= 1) + return first; + else if (size == 2) + return (first + 1); + else + return Call()(comp, *(first + 1), *(first + 2)) + ? (first + 2) + : (first + 1); +} + +} // namespace minmax_heap_detail + + +template +inline void push_minmax_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + minmax_heap_detail::push_heap(first, last, comp); +} + +template +inline void push_minmax_heap(It first, It last) +{ + using namespace minmax_heap_detail; + minmax_heap_detail::push_heap(first, last, std::less<>()); +} + +template +inline void pop_top_minmax_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + pop_heap(first, first, last, comp); +} + +template +inline void pop_top_minmax_heap(It first, It last) +{ + using namespace minmax_heap_detail; + pop_heap(first, first, last, std::less<>()); +} + +template +inline void pop_bottom_minmax_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + It bottom = minmax_heap_detail::bottom_heap(first, last, comp); + pop_heap(first, bottom, last, comp); +} + +template +inline void pop_bottom_minmax_heap(It first, It last) +{ + using namespace minmax_heap_detail; + auto&& comp = std::less<>(); + It bottom = minmax_heap_detail::bottom_heap(first, last, comp); + pop_heap(first, bottom, last, comp); +} + +template +inline void make_minmax_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + return minmax_heap_detail::make_heap(first, last, comp); +} + +template +inline void make_minmax_heap(It first, It last) +{ + using namespace minmax_heap_detail; + return minmax_heap_detail::make_heap(first, last, std::less<>()); +} + +template +inline bool is_minmax_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + return minmax_heap_detail::is_heap(first, last, comp); +} + +template +inline bool is_minmax_heap(It first, It last) +{ + using namespace minmax_heap_detail; + return minmax_heap_detail::is_heap(first, last, std::less<>()); +} + +template +inline decltype(auto) bottom_minmax_heap(It first, It last, Compare comp) +{ + using namespace minmax_heap_detail; + return *minmax_heap_detail::bottom_heap(first, last, comp); +} + +template +inline decltype(auto) bottom_minmax_heap(It first, It last) +{ + using namespace minmax_heap_detail; + return *minmax_heap_detail::bottom_heap(first, last, std::less<>()); +} + + +}}}} // namespace boost::geometry::index::detail + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_MINMAX_HEAP_HPP From 0eff8d759d2165233d6dea58955e20a84f13a713 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 19 Jul 2021 21:18:52 +0200 Subject: [PATCH 19/74] [test][index] Add test for minmax/maxmin heap. --- index/test/Jamfile | 6 +- index/test/minmax_heap.cpp | 282 +++++++++++++++++++++++++++++++++++++ 2 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 index/test/minmax_heap.cpp diff --git a/index/test/Jamfile b/index/test/Jamfile index 2b148a771..48ed5f585 100644 --- a/index/test/Jamfile +++ b/index/test/Jamfile @@ -2,6 +2,9 @@ # # Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. # +# Copyright (c) 2021, 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, # Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) @@ -20,8 +23,9 @@ project boost-geometry-index-test /boost/timer//boost_timer ; -test-suite boost-geometry-index-varray +test-suite boost-geometry-index-detail : + [ run minmax_heap.cpp ] [ run varray_old.cpp ] [ run varray.cpp ] ; diff --git a/index/test/minmax_heap.cpp b/index/test/minmax_heap.cpp new file mode 100644 index 000000000..4dd3a7d82 --- /dev/null +++ b/index/test/minmax_heap.cpp @@ -0,0 +1,282 @@ +// Boost.Geometry + +// Copyright (c) 2021, 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. +// http://www.boost.org/users/license.html + +#include +#include + +#include +#include +#include + +#include +#include + +using namespace boost::geometry::index::detail; + +struct noncopyable +{ + noncopyable(int i_) : i(i_) {} + noncopyable(noncopyable const&) = delete; + noncopyable& operator=(noncopyable const&) = delete; + noncopyable(noncopyable&&) = default; + noncopyable& operator=(noncopyable&&) = default; + bool operator<(noncopyable const& other) const { return i < other.i; } + operator int() const { return i; } + int i; +}; + +template +struct minmax_default +{ + minmax_default() = default; + minmax_default(std::vector const& vec) + : heap(vec.begin(), vec.end()) + { + make_minmax_heap(heap.begin(), heap.end()); + } + T const& top() const + { + return heap[0]; + } + T const& bottom() const + { + return bottom_minmax_heap(heap.begin(), heap.end()); + } + void push(int i) + { + heap.push_back(T(i)); + push_minmax_heap(heap.begin(), heap.end()); + } + void pop_top() + { + pop_top_minmax_heap(heap.begin(), heap.end()); + heap.pop_back(); + } + void pop_bottom() + { + pop_bottom_minmax_heap(heap.begin(), heap.end()); + heap.pop_back(); + } + bool is_heap() const + { + return is_minmax_heap(heap.begin(), heap.end()); + } + bool empty() const + { + return heap.empty(); + } + std::vector heap; +}; + +template +struct minmax_less +{ + minmax_less() = default; + minmax_less(std::vector const& vec) + : heap(vec.begin(), vec.end()) + { + make_minmax_heap(heap.begin(), heap.end(), std::less<>()); + } + T const& top() const + { + return heap[0]; + } + T const& bottom() const + { + return bottom_minmax_heap(heap.begin(), heap.end(), std::less<>()); + } + void push(int i) + { + heap.push_back(T(i)); + push_minmax_heap(heap.begin(), heap.end(), std::less<>()); + } + void pop_top() + { + pop_top_minmax_heap(heap.begin(), heap.end(), std::less<>()); + heap.pop_back(); + } + void pop_bottom() + { + pop_bottom_minmax_heap(heap.begin(), heap.end(), std::less<>()); + heap.pop_back(); + } + bool is_heap() const + { + return is_minmax_heap(heap.begin(), heap.end(), std::less<>()); + } + bool empty() const + { + return heap.empty(); + } + std::vector heap; +}; + +template +struct maxmin_greater +{ + maxmin_greater() = default; + maxmin_greater(std::vector const& vec) + : heap(vec.begin(), vec.end()) + { + make_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); + } + T const& top() const + { + return heap[0]; + } + T const& bottom() const + { + return bottom_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); + } + void push(int i) + { + heap.push_back(T(i)); + push_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); + } + void pop_top() + { + pop_top_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); + heap.pop_back(); + } + void pop_bottom() + { + pop_bottom_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); + heap.pop_back(); + } + bool is_heap() const + { + return is_maxmin_heap(heap.begin(), heap.end(), std::greater<>()); + } + bool empty() const + { + return heap.empty(); + } + std::vector heap; +}; + +template +struct maxmin_default_switch +{ + maxmin_default_switch() = default; + maxmin_default_switch(std::vector const& vec) + : heap(vec.begin(), vec.end()) + { + make_maxmin_heap(heap.begin(), heap.end()); + } + T const& bottom() const + { + return heap[0]; + } + T const& top() const + { + return bottom_maxmin_heap(heap.begin(), heap.end()); + } + void push(int i) + { + heap.push_back(T(i)); + push_maxmin_heap(heap.begin(), heap.end()); + } + void pop_top() + { + pop_bottom_maxmin_heap(heap.begin(), heap.end()); + heap.pop_back(); + } + void pop_bottom() + { + pop_top_maxmin_heap(heap.begin(), heap.end()); + heap.pop_back(); + } + bool is_heap() const + { + return is_maxmin_heap(heap.begin(), heap.end()); + } + bool empty() const + { + return heap.empty(); + } + std::vector heap; +}; + +template +void test() +{ + std::vector vec; + int const n = 20; + for (int i = 0; i < n; ++i) + { + vec.push_back(rand() % n); + } + + { + std::map map; + Heap heap; + for (int i : vec) + { + heap.push(i); + BOOST_CHECK(heap.is_heap()); + + map[i]++; + BOOST_CHECK_EQUAL(heap.top(), map.begin()->first); + BOOST_CHECK_EQUAL(heap.bottom(), (--map.end())->first); + } + + while (! heap.empty()) + { + int i = heap.top(); + BOOST_CHECK_EQUAL(i, map.begin()->first); + BOOST_CHECK_EQUAL(heap.bottom(), (--map.end())->first); + BOOST_CHECK(map[i] > 0); + map[i]--; + if (map[i] <= 0) + map.erase(i); + + heap.pop_top(); + BOOST_CHECK(heap.is_heap()); + } + + BOOST_CHECK(map.empty()); + } + + { + Heap heap(vec); + BOOST_CHECK(heap.is_heap()); + + std::map map; + for (int i : vec) + map[i]++; + BOOST_CHECK_EQUAL(heap.top(), map.begin()->first); + BOOST_CHECK_EQUAL(heap.bottom(), (--map.end())->first); + + while (! heap.empty()) + { + int i = heap.bottom(); + BOOST_CHECK_EQUAL(heap.top(), map.begin()->first); + BOOST_CHECK_EQUAL(i, (--map.end())->first); + BOOST_CHECK(map[i] > 0); + map[i]--; + if (map[i] <= 0) + map.erase(i); + + heap.pop_bottom(); + BOOST_CHECK(heap.is_heap()); + } + + BOOST_CHECK(map.empty()); + } +} + +int test_main(int, char* []) +{ + test>(); + test>(); + test>(); + test>(); + test>(); + + return 0; +} From c0886c35ae00e5865e8a2587bff598b876519df5 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 20 Jul 2021 18:51:31 +0200 Subject: [PATCH 20/74] [index] Add priority_dequeue based on maxmin heap. --- .../index/detail/priority_dequeue.hpp | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 include/boost/geometry/index/detail/priority_dequeue.hpp diff --git a/include/boost/geometry/index/detail/priority_dequeue.hpp b/include/boost/geometry/index/detail/priority_dequeue.hpp new file mode 100644 index 000000000..0ef7b49b8 --- /dev/null +++ b/include/boost/geometry/index/detail/priority_dequeue.hpp @@ -0,0 +1,155 @@ +// Boost.Geometry + +// Copyright (c) 2021, 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. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_PRIORITY_DEQUEUE_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_PRIORITY_DEQUEUE_HPP + +#include + +#include + +namespace boost { namespace geometry { namespace index { namespace detail +{ + +template +< + typename T, + typename Container = std::vector, + typename Compare = std::less +> +class priority_dequeue +{ +public: + using container_type = Container; + using value_compare = Compare; + using value_type = typename Container::value_type; + using size_type = typename Container::size_type; + using reference = typename Container::reference; + using const_reference = typename Container::const_reference; + + priority_dequeue() + : c(), comp() + {} + + explicit priority_dequeue(Compare const& compare) + : c(), comp(compare) + {} + + priority_dequeue(Compare const& compare, Container const& cont) + : c(cont), comp(compare) + { + make_maxmin_heap(c.begin(), c.end(), comp); + } + + priority_dequeue(Compare const& compare, Container&& cont) + : c(std::move(cont)), comp(compare) + { + make_maxmin_heap(c.begin(), c.end(), comp); + } + + template + priority_dequeue(It first, It last) + : c(first, last), comp() + { + make_maxmin_heap(c.begin(), c.end(), comp); + } + + template + priority_dequeue(It first, It last, Compare const& compare) + : c(first, last), comp(compare) + { + make_maxmin_heap(c.begin(), c.end(), comp); + } + + template + priority_dequeue(It first, It last, Compare const& compare, Container const& cont) + : c(cont), comp(compare) + { + c.insert(first, last); + make_maxmin_heap(c.begin(), c.end(), comp); + } + + template + priority_dequeue(It first, It last, Compare const& compare, Container&& cont) + : c(std::move(cont)), comp(compare) + { + c.insert(first, last); + make_maxmin_heap(c.begin(), c.end(), comp); + } + + const_reference top() const + { + return *c.begin(); + } + + const_reference bottom() const + { + return bottom_maxmin_heap(c.begin(), c.end(), comp); + } + + void push(const value_type& value) + { + c.push_back(value); + push_maxmin_heap(c.begin(), c.end(), comp); + } + + void push(value_type&& value) + { + c.push_back(std::move(value)); + push_maxmin_heap(c.begin(), c.end(), comp); + } + + template + void emplace(Args&& ...args) + { + c.emplace_back(std::forward(args)...); + push_maxmin_heap(c.begin(), c.end(), comp); + } + + void pop_top() + { + pop_top_maxmin_heap(c.begin(), c.end(), comp); + c.pop_back(); + } + + void pop_bottom() + { + pop_bottom_maxmin_heap(c.begin(), c.end(), comp); + c.pop_back(); + } + + bool empty() const + { + return c.empty(); + } + + size_t size() const + { + return c.size(); + } + + void clear() + { + c.clear(); + } + + void swap(priority_dequeue& other) + { + using std::swap; + std::swap(c, other.c); + std::swap(comp, other.comp); + } + +protected: + Container c; + Compare comp; +}; + +}}}} // namespace boost::geometry::index::detail + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_PRIORITY_DEQUEUE_HPP From 5d9a03a9438a67e8f46755bec8f8881608c2c940 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 20 Jul 2021 18:53:08 +0200 Subject: [PATCH 21/74] [index] Replace sort with priority_dequeue in iterative knn query. --- .../geometry/index/detail/predicates.hpp | 8 +- .../detail/rtree/visitors/distance_query.hpp | 263 +++++++++--------- .../detail/rtree/visitors/spatial_query.hpp | 41 +-- 3 files changed, 148 insertions(+), 164 deletions(-) diff --git a/include/boost/geometry/index/detail/predicates.hpp b/include/boost/geometry/index/detail/predicates.hpp index 0ae8defe8..22db3bf35 100644 --- a/include/boost/geometry/index/detail/predicates.hpp +++ b/include/boost/geometry/index/detail/predicates.hpp @@ -619,11 +619,13 @@ struct predicates_check_impl, Tag, First, Last> } }; -template +template inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i, Strategy const& s) { - return detail::predicates_check_impl - ::apply(p, v, i, s); + return detail::predicates_check_impl + < + Predicates, Tag, 0, predicates_length::value + >::apply(p, v, i, s); } // ------------------------------------------------------------------ // diff --git a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp index a40dbfe84..df48ee0b7 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp @@ -15,6 +15,10 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_DISTANCE_QUERY_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_DISTANCE_QUERY_HPP +#include + +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { @@ -40,6 +44,16 @@ struct pair_first_greater } }; +template +struct priority_queue : std::priority_queue, Comp> +{ + priority_queue() = default; + void clear() + { + this->c.clear(); + } +}; + template class distance_query_result @@ -140,8 +154,6 @@ public: typedef typename calculate_value_distance::result_type value_distance_type; typedef typename calculate_node_distance::result_type node_distance_type; - static const std::size_t predicates_len = index::detail::predicates_length::value; - inline distance_query(parameters_type const& parameters, translator_type const& translator, Predicates const& pred, OutIter out_it) : m_parameters(parameters), m_translator(translator) , m_pred(pred) @@ -151,29 +163,26 @@ public: inline void operator()(internal_node const& n) { - typedef typename rtree::elements_type::type elements_type; + namespace id = index::detail; // array of active nodes - typedef typename index::detail::rtree::container_from_elements_type< - elements_type, - std::pair - >::type active_branch_list_type; + using active_branch_list_type = typename index::detail::rtree::container_from_elements_type + < + typename rtree::elements_type::type, + std::pair + >::type; active_branch_list_type active_branch_list; active_branch_list.reserve(m_parameters.get_max_elements()); - elements_type const& elements = rtree::elements(n); + auto const& elements = rtree::elements(n); // fill array of nodes meeting predicates - for (typename elements_type::const_iterator it = elements.begin(); - it != elements.end(); ++it) + for (auto it = elements.begin(); it != elements.end(); ++it) { // if current node meets predicates // 0 - dummy value - if ( index::detail::predicates_check - < - index::detail::bounds_tag, 0, predicates_len - >(m_pred, 0, it->first, m_strategy) ) + if (id::predicates_check(m_pred, 0, it->first, m_strategy) ) { // calculate node's distance(s) for distance predicate node_distance_type node_distance; @@ -204,8 +213,7 @@ public: std::sort(active_branch_list.begin(), active_branch_list.end(), pair_first_less()); // recursively visit nodes - for ( typename active_branch_list_type::const_iterator it = active_branch_list.begin(); - it != active_branch_list.end() ; ++it ) + for (auto it = active_branch_list.begin(); it != active_branch_list.end() ; ++it) { // if current node is further than furthest neighbor, the rest of nodes also will be further if ( m_result.has_enough_neighbors() && @@ -245,18 +253,15 @@ public: inline void operator()(leaf const& n) { - typedef typename rtree::elements_type::type elements_type; - elements_type const& elements = rtree::elements(n); + namespace id = index::detail; + + auto const& elements = rtree::elements(n); // search leaf for closest value meeting predicates - for (typename elements_type::const_iterator it = elements.begin(); - it != elements.end(); ++it) + for (auto it = elements.begin(); it != elements.end(); ++it) { // if value meets predicates - if ( index::detail::predicates_check - < - index::detail::value_tag, 0, predicates_len - >(m_pred, *it, m_translator(*it), m_strategy) ) + if (id::predicates_check(m_pred, *it, m_translator(*it), m_strategy)) { // calculate values distance for distance predicate value_distance_type value_distance; @@ -331,88 +336,93 @@ public: typedef typename allocators_type::const_reference const_reference; typedef typename allocators_type::node_pointer node_pointer; - static const std::size_t predicates_len = index::detail::predicates_length::value; - typedef typename rtree::elements_type::type internal_elements; typedef typename internal_elements::const_iterator internal_iterator; typedef typename rtree::elements_type::type leaf_elements; - typedef std::pair branch_data; - typedef std::vector internal_heap_type; + using branch_data = std::pair; + using branches_type = priority_queue; + using neighbor_data = std::pair; + using neighbors_type = priority_dequeue, pair_first_greater>; inline distance_query_incremental() - : m_translator(NULL) + : m_translator(nullptr) // , m_pred() - , current_neighbor((std::numeric_limits::max)()) + , m_neighbors_count(0) + , m_neighbor_ptr(nullptr) // , m_strategy_type() {} inline distance_query_incremental(parameters_type const& params, translator_type const& translator, Predicates const& pred) : m_translator(::boost::addressof(translator)) , m_pred(pred) - , current_neighbor((std::numeric_limits::max)()) + , m_neighbors_count(0) + , m_neighbor_ptr(nullptr) , m_strategy(index::detail::get_strategy(params)) - { - BOOST_GEOMETRY_INDEX_ASSERT(0 < max_count(), "k must be greather than 0"); - } + {} const_reference dereference() const { - return *(neighbors[current_neighbor].second); + return *m_neighbor_ptr; } void initialize(node_pointer root) { - rtree::apply_visitor(*this, *root); - increment(); + if (0 < max_count()) + { + rtree::apply_visitor(*this, *root); + increment(); + } } void increment() { for (;;) { - size_type new_neighbor = current_neighbor == (std::numeric_limits::max)() ? 0 : current_neighbor + 1; - - if ( internal_heap.empty() ) + if (m_branches.empty()) { - if ( new_neighbor < neighbors.size() ) - current_neighbor = new_neighbor; + // there exists a next closest neighbor so we can increment + if (! m_neighbors.empty()) + { + m_neighbor_ptr = m_neighbors.top().second; + ++m_neighbors_count; + m_neighbors.pop_top(); + } else { - current_neighbor = (std::numeric_limits::max)(); - // clear() is used to disable the condition above - neighbors.clear(); + // there aren't any neighbors left, end + m_neighbor_ptr = nullptr; + m_neighbors_count = max_count(); } return; } else { - branch_data const& closest_branch = internal_heap.front(); - node_distance_type const& closest_distance = closest_branch.first; + branch_data const& closest_branch = m_branches.top(); - // if there are no nodes which can have closer values, set new value - if ( new_neighbor < neighbors.size() && - // NOTE: In order to use <= current neighbor can't be sorted again - neighbors[new_neighbor].first <= closest_distance ) + // if next neighbor is closer or as close as the closest branch, set next neighbor + if (! m_neighbors.empty() && m_neighbors.top().first <= closest_branch.first ) { - current_neighbor = new_neighbor; + m_neighbor_ptr = m_neighbors.top().second; + ++m_neighbors_count; + m_neighbors.pop_top(); return; } - // if node is further than the furthest neighbor, following nodes will also be further - BOOST_GEOMETRY_INDEX_ASSERT(neighbors.size() <= max_count(), "unexpected neighbors count"); - if ( max_count() <= neighbors.size() && - neighbors.back().first <= closest_distance ) + BOOST_GEOMETRY_INDEX_ASSERT(m_neighbors_count + m_neighbors.size() <= max_count(), "unexpected neighbors count"); + + // if there is enough neighbors and there is no closer branch + if (m_neighbors_count + m_neighbors.size() == max_count() + && (m_neighbors.empty() || m_neighbors.bottom().first <= closest_branch.first)) { - internal_heap.clear(); + m_branches.clear(); continue; } else { node_pointer ptr = closest_branch.second; - std::pop_heap(internal_heap.begin(), internal_heap.end(), pair_first_greater()); - internal_heap.pop_back(); + m_branches.pop(); rtree::apply_visitor(*this, *ptr); } @@ -422,17 +432,12 @@ public: bool is_end() const { - return (std::numeric_limits::max)() == current_neighbor; + return m_neighbor_ptr == nullptr; } friend bool operator==(distance_query_incremental const& l, distance_query_incremental const& r) { - BOOST_GEOMETRY_INDEX_ASSERT(l.current_neighbor != r.current_neighbor || - (std::numeric_limits::max)() == l.current_neighbor || - (std::numeric_limits::max)() == r.current_neighbor || - l.neighbors[l.current_neighbor].second == r.neighbors[r.current_neighbor].second, - "not corresponding iterators"); - return l.current_neighbor == r.current_neighbor; + return l.m_neighbors_count == r.m_neighbors_count; } // Put node's elements into the list of active branches if those elements meets predicates @@ -440,39 +445,37 @@ public: // and aren't further than found neighbours (if there is enough neighbours) inline void operator()(internal_node const& n) { - typedef typename rtree::elements_type::type elements_type; - elements_type const& elements = rtree::elements(n); + namespace id = index::detail; + + auto const& elements = rtree::elements(n); // fill active branch list array of nodes meeting predicates - for ( typename elements_type::const_iterator it = elements.begin() ; it != elements.end() ; ++it ) + for (auto it = elements.begin() ; it != elements.end() ; ++it) { - // if current node meets predicates + // if current node doesn't meet predicates // 0 - dummy value - if ( index::detail::predicates_check - < - index::detail::bounds_tag, 0, predicates_len - >(m_pred, 0, it->first, m_strategy) ) + if (! id::predicates_check(m_pred, 0, it->first, m_strategy)) { - // calculate node's distance(s) for distance predicate - node_distance_type node_distance; - // if distance isn't ok - move to the next node - if ( !calculate_node_distance::apply(predicate(), it->first, - m_strategy, node_distance) ) - { - continue; - } - - // if current node is further than found neighbors - don't analyze it - if ( max_count() <= neighbors.size() && - neighbors.back().first <= node_distance ) - { - continue; - } - - // add current node's data into the queue - internal_heap.push_back(std::make_pair(node_distance, it->second)); - std::push_heap(internal_heap.begin(), internal_heap.end(), pair_first_greater()); + continue; } + + // calculate node's distance(s) for distance predicate + node_distance_type node_distance; + // if distance isn't ok + if (! calculate_node_distance::apply(predicate(), it->first, m_strategy, node_distance)) + { + continue; + } + + // if there is enough neighbors and there is no closer branch + if (m_neighbors_count + m_neighbors.size() == max_count() + && (m_neighbors.empty() || m_neighbors.bottom().first <= node_distance)) + { + continue; + } + + // add current node into the queue + m_branches.push(std::make_pair(node_distance, it->second)); } } @@ -481,49 +484,42 @@ public: // and aren't further than already found neighbours (if there is enough neighbours) inline void operator()(leaf const& n) { - typedef typename rtree::elements_type::type elements_type; - elements_type const& elements = rtree::elements(n); + namespace id = index::detail; + + auto const& elements = rtree::elements(n); - // store distance to the furthest neighbour - bool not_enough_neighbors = neighbors.size() < max_count(); - value_distance_type greatest_distance = !not_enough_neighbors ? neighbors.back().first : (std::numeric_limits::max)(); - // search leaf for closest value meeting predicates - for ( typename elements_type::const_iterator it = elements.begin() ; it != elements.end() ; ++it) + for (auto it = elements.begin() ; it != elements.end() ; ++it) { - // if value meets predicates - if ( index::detail::predicates_check - < - index::detail::value_tag, 0, predicates_len - >(m_pred, *it, (*m_translator)(*it), m_strategy) ) + // if value doesn't meet predicates + if (! id::predicates_check(m_pred, *it, (*m_translator)(*it), m_strategy)) { - // calculate values distance for distance predicate - value_distance_type value_distance; - // if distance is ok - if ( calculate_value_distance::apply(predicate(), (*m_translator)(*it), - m_strategy, value_distance) ) - { - // if there is not enough values or current value is closer than furthest neighbour - if ( not_enough_neighbors || value_distance < greatest_distance ) - { - neighbors.push_back(std::make_pair(value_distance, boost::addressof(*it))); - } - } + continue; + } + + // calculate values distance for distance predicate + value_distance_type value_distance; + // if distance isn't ok + if (! calculate_value_distance::apply(predicate(), (*m_translator)(*it), + m_strategy, value_distance)) + { + continue; + } + + // if there is enough neighbors and there is no closer neighbor + if (m_neighbors_count + m_neighbors.size() == max_count() + && (m_neighbors.empty() || m_neighbors.bottom().first <= value_distance)) + { + continue; + } + + // add current value into the queue + m_neighbors.push(std::make_pair(value_distance, boost::addressof(*it))); + if (m_neighbors_count + m_neighbors.size() > max_count()) + { + m_neighbors.pop_bottom(); } } - - // TODO: sort is probably suboptimal. - // An alternative would be std::set, but it'd probably add constant cost. - // Ideally replace this with double-ended priority queue, e.g. min-max heap. - // NOTE: A condition in increment() relies on the fact that current neighbor doesn't - // participate in sorting anymore. - - // sort array - size_type sort_first = current_neighbor == (std::numeric_limits::max)() ? 0 : current_neighbor + 1; - std::sort(neighbors.begin() + sort_first, neighbors.end(), pair_first_less()); - // remove furthest values - if ( max_count() < neighbors.size() ) - neighbors.resize(max_count()); } private: @@ -541,9 +537,10 @@ private: Predicates m_pred; - internal_heap_type internal_heap; - std::vector< std::pair > neighbors; - size_type current_neighbor; + branches_type m_branches; + neighbors_type m_neighbors; + size_type m_neighbors_count; + const value_type * m_neighbor_ptr; strategy_type m_strategy; }; diff --git a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp index f0d30162c..f4799137e 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp @@ -35,27 +35,22 @@ struct spatial_query typedef typename allocators_type::size_type size_type; - static const std::size_t predicates_len = index::detail::predicates_length::value; - inline spatial_query(parameters_type const& par, translator_type const& t, Predicates const& p, OutIter out_it) : tr(t), pred(p), out_iter(out_it), found_count(0), strategy(index::detail::get_strategy(par)) {} inline void operator()(internal_node const& n) { - typedef typename rtree::elements_type::type elements_type; - elements_type const& elements = rtree::elements(n); + namespace id = index::detail; + + auto const& elements = rtree::elements(n); // traverse nodes meeting predicates - for (typename elements_type::const_iterator it = elements.begin(); - it != elements.end(); ++it) + for (auto it = elements.begin(); it != elements.end(); ++it) { // if node meets predicates // 0 - dummy value - if ( index::detail::predicates_check - < - index::detail::bounds_tag, 0, predicates_len - >(pred, 0, it->first, strategy) ) + if (id::predicates_check(pred, 0, it->first, strategy)) { rtree::apply_visitor(*this, *it->second); } @@ -64,18 +59,15 @@ struct spatial_query inline void operator()(leaf const& n) { - typedef typename rtree::elements_type::type elements_type; - elements_type const& elements = rtree::elements(n); + namespace id = index::detail; + + auto const& elements = rtree::elements(n); // get all values meeting predicates - for (typename elements_type::const_iterator it = elements.begin(); - it != elements.end(); ++it) + for (auto it = elements.begin(); it != elements.end(); ++it) { // if value meets predicates - if ( index::detail::predicates_check - < - index::detail::value_tag, 0, predicates_len - >(pred, *it, tr(*it), strategy) ) + if (id::predicates_check(pred, *it, tr(*it), strategy)) { *out_iter = *it; ++out_iter; @@ -119,8 +111,6 @@ public: typedef typename rtree::elements_type::type leaf_elements; typedef typename rtree::elements_type::type::const_iterator leaf_iterator; - static const std::size_t predicates_len = index::detail::predicates_length::value; - inline spatial_query_incremental() : m_translator(NULL) // , m_pred() @@ -171,6 +161,7 @@ public: void search_value() { + namespace id = index::detail; for (;;) { // if leaf is choosen, move to the next value in leaf @@ -180,10 +171,7 @@ public: { // return if next value is found value_type const& v = *m_current; - if (index::detail::predicates_check - < - index::detail::value_tag, 0, predicates_len - >(m_pred, v, (*m_translator)(v), m_strategy)) + if (id::predicates_check(m_pred, v, (*m_translator)(v), m_strategy)) { return; } @@ -214,10 +202,7 @@ public: ++m_internal_stack.back().first; // next node is found, push it to the stack - if (index::detail::predicates_check - < - index::detail::bounds_tag, 0, predicates_len - >(m_pred, 0, it->first, m_strategy)) + if (id::predicates_check(m_pred, 0, it->first, m_strategy)) { rtree::apply_visitor(*this, *(it->second)); } From 6daaf2162d762fc344c12a9a4b864d789f4305db Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 22 Jul 2021 02:02:04 +0200 Subject: [PATCH 22/74] [index] Refactor distance_query, remove recursion, change branches handling. Remove recursion, keep one container of branches to traverse. Replace stack of sorted branches per level with priority_queue. Prioritize branches based on distance and level to traverse the closest and the deepest nodes first. --- .../index/detail/priority_dequeue.hpp | 5 - .../detail/rtree/visitors/distance_query.hpp | 314 +++++++++--------- include/boost/geometry/index/rtree.hpp | 9 +- 3 files changed, 156 insertions(+), 172 deletions(-) diff --git a/include/boost/geometry/index/detail/priority_dequeue.hpp b/include/boost/geometry/index/detail/priority_dequeue.hpp index 0ef7b49b8..bbe563aba 100644 --- a/include/boost/geometry/index/detail/priority_dequeue.hpp +++ b/include/boost/geometry/index/detail/priority_dequeue.hpp @@ -133,11 +133,6 @@ public: return c.size(); } - void clear() - { - c.clear(); - } - void swap(priority_dequeue& other) { using std::swap; diff --git a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp index df48ee0b7..e4f53ffe6 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp @@ -45,89 +45,97 @@ struct pair_first_greater }; template -struct priority_queue : std::priority_queue, Comp> +struct priority_dequeue : index::detail::priority_dequeue, Comp> { - priority_queue() = default; + priority_dequeue() = default; + void reserve(typename std::vector::size_type n) + { + this->c.reserve(n); + } void clear() { this->c.clear(); } }; +template +struct priority_queue : std::priority_queue, Comp> +{ + priority_queue() = default; + void reserve(typename std::vector::size_type n) + { + this->c.reserve(n); + } + void clear() + { + this->c.clear(); + } +}; -template +template class distance_query_result { -public: - typedef DistanceType distance_type; + using neighbor_data = std::pair; + using neighbors_type = std::vector; + using size_type = typename neighbors_type::size_type; - inline explicit distance_query_result(size_t k, OutIt out_it) - : m_count(k), m_out_it(out_it) +public: + inline distance_query_result(size_type k) + : m_count(k) { BOOST_GEOMETRY_INDEX_ASSERT(0 < m_count, "Number of neighbors should be greater than 0"); m_neighbors.reserve(m_count); } - inline void store(Value const& val, distance_type const& curr_comp_dist) + inline void store(DistanceType const& distance, const Value * value_ptr) { - if ( m_neighbors.size() < m_count ) + if (m_neighbors.size() < m_count) { - m_neighbors.push_back(std::make_pair(curr_comp_dist, val)); + m_neighbors.push_back(std::make_pair(distance, value_ptr)); - if ( m_neighbors.size() == m_count ) - std::make_heap(m_neighbors.begin(), m_neighbors.end(), pair_first_less()); - } - else - { - if ( curr_comp_dist < m_neighbors.front().first ) + if (m_neighbors.size() == m_count) { - std::pop_heap(m_neighbors.begin(), m_neighbors.end(), pair_first_less()); - m_neighbors.back().first = curr_comp_dist; - m_neighbors.back().second = val; - std::push_heap(m_neighbors.begin(), m_neighbors.end(), pair_first_less()); + std::make_heap(m_neighbors.begin(), m_neighbors.end(), pair_first_less()); } } + else if (distance < m_neighbors.front().first) + { + std::pop_heap(m_neighbors.begin(), m_neighbors.end(), pair_first_less()); + m_neighbors.back().first = distance; + m_neighbors.back().second = value_ptr; + std::push_heap(m_neighbors.begin(), m_neighbors.end(), pair_first_less()); + } } - inline bool has_enough_neighbors() const + inline bool ignore_branch(DistanceType const& distance) const { - return m_count <= m_neighbors.size(); + return m_neighbors.size() == m_count + && m_neighbors.front().first <= distance; } - inline distance_type greatest_comparable_distance() const + template + inline size_type finish(OutIt out_it) const { - // greatest distance is in the first neighbor only - // if there is at least m_count values found - // this is just for safety reasons since is_comparable_distance_valid() is checked earlier - // TODO - may be replaced by ASSERT - return m_neighbors.size() < m_count - ? (std::numeric_limits::max)() - : m_neighbors.front().first; - } - - inline size_t finish() - { - typedef typename std::vector< std::pair >::const_iterator neighbors_iterator; - for ( neighbors_iterator it = m_neighbors.begin() ; it != m_neighbors.end() ; ++it, ++m_out_it ) - *m_out_it = it->second; + for (auto const& p : m_neighbors) + { + *out_it = *(p.second); + ++out_it; + } return m_neighbors.size(); } private: - size_t m_count; - OutIt m_out_it; - - std::vector< std::pair > m_neighbors; + size_type m_count; + neighbors_type m_neighbors; }; template < typename MembersHolder, typename Predicates, - std::size_t DistancePredicateIndex, - typename OutIter + std::size_t DistancePredicateIndex > class distance_query : public MembersHolder::visitor_const @@ -154,140 +162,126 @@ public: typedef typename calculate_value_distance::result_type value_distance_type; typedef typename calculate_node_distance::result_type node_distance_type; - inline distance_query(parameters_type const& parameters, translator_type const& translator, Predicates const& pred, OutIter out_it) + typedef typename allocators_type::size_type size_type; + typedef typename allocators_type::node_pointer node_pointer; + + struct branch_data + { + branch_data(node_distance_type d, size_type l, node_pointer p) + : distance(d), level(l), ptr(p) + {} + + node_distance_type distance; + size_type level; + node_pointer ptr; + }; + + struct branch_data_comp + { + bool operator()(branch_data const& b1, branch_data const& b2) const + { + return b1.distance > b2.distance || (b1.distance == b2.distance && b1.level < b2.level); + } + }; + + inline distance_query(parameters_type const& parameters, translator_type const& translator, Predicates const& pred) : m_parameters(parameters), m_translator(translator) , m_pred(pred) - , m_result(nearest_predicate_access::get(m_pred).count, out_it) + , m_result(nearest_predicate_access::get(m_pred).count) , m_strategy(index::detail::get_strategy(parameters)) - {} + { + //m_branches.reserve(m_parameters.get_max_elements() * levels_count); ? + } + + template + size_type apply(node_pointer root, OutIter out_it) + { + m_level = 1; + rtree::apply_visitor(*this, *root); + + for (;;) + { + if (m_branches.empty()) + { + break; + } + + if (m_result.ignore_branch(m_branches.top().distance)) + { + break; + } + + node_pointer ptr = m_branches.top().ptr; + m_level = m_branches.top().level + 1; + m_branches.pop(); + rtree::apply_visitor(*this, *ptr); + } + + return m_result.finish(out_it); + } inline void operator()(internal_node const& n) { namespace id = index::detail; - // array of active nodes - using active_branch_list_type = typename index::detail::rtree::container_from_elements_type - < - typename rtree::elements_type::type, - std::pair - >::type; - - active_branch_list_type active_branch_list; - active_branch_list.reserve(m_parameters.get_max_elements()); - - auto const& elements = rtree::elements(n); - // fill array of nodes meeting predicates - for (auto it = elements.begin(); it != elements.end(); ++it) + for (auto const& p : rtree::elements(n)) { // if current node meets predicates // 0 - dummy value - if (id::predicates_check(m_pred, 0, it->first, m_strategy) ) + if (! id::predicates_check(m_pred, 0, p.first, m_strategy)) { - // calculate node's distance(s) for distance predicate - node_distance_type node_distance; - // if distance isn't ok - move to the next node - if ( !calculate_node_distance::apply(predicate(), it->first, - m_strategy, node_distance) ) - { - continue; - } - - // if current node is further than found neighbors - don't analyze it - if ( m_result.has_enough_neighbors() && - is_node_prunable(m_result.greatest_comparable_distance(), node_distance) ) - { - continue; - } - - // add current node's data into the list - active_branch_list.push_back( std::make_pair(node_distance, it->second) ); + continue; } + + // calculate node's distance(s) for distance predicate + node_distance_type node_distance; + // if distance isn't ok - move to the next node + if (! calculate_node_distance::apply(predicate(), p.first, + m_strategy, node_distance)) + { + continue; + } + + // if current node is further than found neighbors - don't analyze it + if (m_result.ignore_branch(node_distance)) + { + continue; + } + + // add current node's data into the list + m_branches.push(branch_data(node_distance, m_level, p.second)); } - - // if there aren't any nodes in ABL - return - if ( active_branch_list.empty() ) - return; - - // sort array - std::sort(active_branch_list.begin(), active_branch_list.end(), pair_first_less()); - - // recursively visit nodes - for (auto it = active_branch_list.begin(); it != active_branch_list.end() ; ++it) - { - // if current node is further than furthest neighbor, the rest of nodes also will be further - if ( m_result.has_enough_neighbors() && - is_node_prunable(m_result.greatest_comparable_distance(), it->first) ) - break; - - rtree::apply_visitor(*this, *(it->second)); - } - - // ALTERNATIVE VERSION - use heap instead of sorted container - // It seems to be faster for greater MaxElements and slower otherwise - // CONSIDER: using one global container/heap for active branches - // instead of a sorted container per level - // This would also change the way how branches are traversed! - // The same may be applied to the iterative version which btw suffers - // from the copying of the whole containers on resize of the ABLs container - - //// make a heap - //std::make_heap(active_branch_list.begin(), active_branch_list.end(), pair_first_greater()); - - //// recursively visit nodes - //while ( !active_branch_list.empty() ) - //{ - // //if current node is further than furthest neighbor, the rest of nodes also will be further - // if ( m_result.has_enough_neighbors() - // && is_node_prunable(m_result.greatest_comparable_distance(), active_branch_list.front().first) ) - // { - // break; - // } - - // rtree::apply_visitor(*this, *(active_branch_list.front().second)); - - // std::pop_heap(active_branch_list.begin(), active_branch_list.end(), pair_first_greater()); - // active_branch_list.pop_back(); - //} } inline void operator()(leaf const& n) { namespace id = index::detail; - auto const& elements = rtree::elements(n); - // search leaf for closest value meeting predicates - for (auto it = elements.begin(); it != elements.end(); ++it) + for (auto const& v : rtree::elements(n)) { // if value meets predicates - if (id::predicates_check(m_pred, *it, m_translator(*it), m_strategy)) + if (! id::predicates_check(m_pred, v, m_translator(v), m_strategy)) { - // calculate values distance for distance predicate - value_distance_type value_distance; - // if distance is ok - if ( calculate_value_distance::apply(predicate(), m_translator(*it), - m_strategy, value_distance) ) - { - // store value - m_result.store(*it, value_distance); - } + continue; } + + // calculate values distance for distance predicate + value_distance_type value_distance; + // if distance is ok + if (! calculate_value_distance::apply(predicate(), m_translator(v), + m_strategy, value_distance)) + { + continue; + } + + // store value + m_result.store(value_distance, boost::addressof(v)); } } - inline size_t finish() - { - return m_result.finish(); - } - private: - template - static inline bool is_node_prunable(Distance const& greatest_dist, node_distance_type const& d) - { - return greatest_dist <= d; - } - nearest_predicate_type const& predicate() const { return nearest_predicate_access::get(m_pred); @@ -297,7 +291,9 @@ private: translator_type const& m_translator; Predicates m_pred; - distance_query_result m_result; + distance_query_result m_result; + priority_queue m_branches; + size_type m_level; strategy_type m_strategy; }; @@ -343,7 +339,7 @@ public: using branch_data = std::pair; using branches_type = priority_queue; using neighbor_data = std::pair; - using neighbors_type = priority_dequeue, pair_first_greater>; + using neighbors_type = priority_dequeue; inline distance_query_incremental() : m_translator(nullptr) @@ -447,14 +443,12 @@ public: { namespace id = index::detail; - auto const& elements = rtree::elements(n); - // fill active branch list array of nodes meeting predicates - for (auto it = elements.begin() ; it != elements.end() ; ++it) + for (auto const& p : rtree::elements(n)) { // if current node doesn't meet predicates // 0 - dummy value - if (! id::predicates_check(m_pred, 0, it->first, m_strategy)) + if (! id::predicates_check(m_pred, 0, p.first, m_strategy)) { continue; } @@ -462,7 +456,7 @@ public: // calculate node's distance(s) for distance predicate node_distance_type node_distance; // if distance isn't ok - if (! calculate_node_distance::apply(predicate(), it->first, m_strategy, node_distance)) + if (! calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance)) { continue; } @@ -475,7 +469,7 @@ public: } // add current node into the queue - m_branches.push(std::make_pair(node_distance, it->second)); + m_branches.push(std::make_pair(node_distance, p.second)); } } @@ -486,13 +480,11 @@ public: { namespace id = index::detail; - auto const& elements = rtree::elements(n); - // search leaf for closest value meeting predicates - for (auto it = elements.begin() ; it != elements.end() ; ++it) + for (auto const& v : rtree::elements(n)) { // if value doesn't meet predicates - if (! id::predicates_check(m_pred, *it, (*m_translator)(*it), m_strategy)) + if (! id::predicates_check(m_pred, v, (*m_translator)(v), m_strategy)) { continue; } @@ -500,7 +492,7 @@ public: // calculate values distance for distance predicate value_distance_type value_distance; // if distance isn't ok - if (! calculate_value_distance::apply(predicate(), (*m_translator)(*it), + if (! calculate_value_distance::apply(predicate(), (*m_translator)(v), m_strategy, value_distance)) { continue; @@ -514,7 +506,7 @@ public: } // add current value into the queue - m_neighbors.push(std::make_pair(value_distance, boost::addressof(*it))); + m_neighbors.push(std::make_pair(value_distance, boost::addressof(v))); if (m_neighbors_count + m_neighbors.size() > max_count()) { m_neighbors.pop_bottom(); diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index 2b7e3811d..24eba480f 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -1920,13 +1920,10 @@ private: detail::rtree::visitors::distance_query< members_holder, Predicates, - distance_predicate_index, - OutIter - > distance_v(m_members.parameters(), m_members.translator(), predicates, out_it); + distance_predicate_index + > distance_v(m_members.parameters(), m_members.translator(), predicates); - detail::rtree::apply_visitor(distance_v, *m_members.root); - - return distance_v.finish(); + return distance_v.apply(m_members.root, out_it); } /*! From 5701d7bef0a6d167edf259d8c1e0dfe1c253dfd7 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 22 Jul 2021 14:59:27 +0200 Subject: [PATCH 23/74] [index] Refactor spatial_query, remove recursion. --- .../detail/rtree/visitors/spatial_query.hpp | 39 ++++++++++++++----- include/boost/geometry/index/rtree.hpp | 4 +- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp index f4799137e..4aa579530 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp @@ -33,26 +33,44 @@ struct spatial_query typedef typename MembersHolder::internal_node internal_node; typedef typename MembersHolder::leaf leaf; + typedef typename allocators_type::node_pointer node_pointer; typedef typename allocators_type::size_type size_type; inline spatial_query(parameters_type const& par, translator_type const& t, Predicates const& p, OutIter out_it) : tr(t), pred(p), out_iter(out_it), found_count(0), strategy(index::detail::get_strategy(par)) {} + size_type apply(node_pointer root) + { + rtree::apply_visitor(*this, *root); + + for (;;) + { + if (m_internal_stack.empty()) + { + break; + } + + node_pointer ptr = m_internal_stack.back(); + m_internal_stack.pop_back(); + rtree::apply_visitor(*this, *ptr); + } + + return found_count; + } + inline void operator()(internal_node const& n) { namespace id = index::detail; - auto const& elements = rtree::elements(n); - // traverse nodes meeting predicates - for (auto it = elements.begin(); it != elements.end(); ++it) + for (auto const& p : rtree::elements(n)) { // if node meets predicates // 0 - dummy value - if (id::predicates_check(pred, 0, it->first, strategy)) + if (id::predicates_check(pred, 0, p.first, strategy)) { - rtree::apply_visitor(*this, *it->second); + m_internal_stack.push_back(p.second); } } } @@ -61,15 +79,13 @@ struct spatial_query { namespace id = index::detail; - auto const& elements = rtree::elements(n); - // get all values meeting predicates - for (auto it = elements.begin(); it != elements.end(); ++it) + for (auto const& v : rtree::elements(n)) { // if value meets predicates - if (id::predicates_check(pred, *it, tr(*it), strategy)) + if (id::predicates_check(pred, v, tr(v), strategy)) { - *out_iter = *it; + *out_iter = v; ++out_iter; ++found_count; @@ -77,10 +93,13 @@ struct spatial_query } } +private: translator_type const& tr; Predicates pred; + std::vector m_internal_stack; + OutIter out_iter; size_type found_count; diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index 24eba480f..5a4941cfb 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -1900,9 +1900,7 @@ private: detail::rtree::visitors::spatial_query find_v(m_members.parameters(), m_members.translator(), predicates, out_it); - detail::rtree::apply_visitor(find_v, *m_members.root); - - return find_v.found_count; + return find_v.apply(m_members.root); } /*! From f838b88a9d852aba997fc073df2ca4ffaf7ebdd0 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 22 Jul 2021 17:16:35 +0200 Subject: [PATCH 24/74] [index] Simplify rtree query(), qbegin() and qend(). --- .../index/detail/rtree/query_iterators.hpp | 8 +- .../detail/rtree/visitors/distance_query.hpp | 48 ++++--- .../detail/rtree/visitors/spatial_query.hpp | 2 + include/boost/geometry/index/rtree.hpp | 119 ++++++------------ 4 files changed, 69 insertions(+), 108 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/query_iterators.hpp b/include/boost/geometry/index/detail/rtree/query_iterators.hpp index 8822bcf04..28b19aed0 100644 --- a/include/boost/geometry/index/detail/rtree/query_iterators.hpp +++ b/include/boost/geometry/index/detail/rtree/query_iterators.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019. -// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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, @@ -134,14 +134,14 @@ private: visitor_type m_visitor; }; -template +template class distance_query_iterator { typedef typename MembersHolder::parameters_type parameters_type; typedef typename MembersHolder::translator_type translator_type; typedef typename MembersHolder::allocators_type allocators_type; - typedef visitors::distance_query_incremental visitor_type; + typedef visitors::distance_query_incremental visitor_type; typedef typename visitor_type::node_pointer node_pointer; public: diff --git a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp index e4f53ffe6..b7d119f10 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp @@ -17,6 +17,7 @@ #include +#include #include namespace boost { namespace geometry { namespace index { @@ -48,24 +49,24 @@ template struct priority_dequeue : index::detail::priority_dequeue, Comp> { priority_dequeue() = default; - void reserve(typename std::vector::size_type n) - { - this->c.reserve(n); - } - void clear() - { - this->c.clear(); - } + //void reserve(typename std::vector::size_type n) + //{ + // this->c.reserve(n); + //} + //void clear() + //{ + // this->c.clear(); + //} }; template struct priority_queue : std::priority_queue, Comp> { priority_queue() = default; - void reserve(typename std::vector::size_type n) - { - this->c.reserve(n); - } + //void reserve(typename std::vector::size_type n) + //{ + // this->c.reserve(n); + //} void clear() { this->c.clear(); @@ -131,12 +132,7 @@ private: neighbors_type m_neighbors; }; -template -< - typename MembersHolder, - typename Predicates, - std::size_t DistancePredicateIndex -> +template class distance_query : public MembersHolder::visitor_const { @@ -153,7 +149,10 @@ public: typedef typename MembersHolder::internal_node internal_node; typedef typename MembersHolder::leaf leaf; - typedef index::detail::predicates_element nearest_predicate_access; + typedef index::detail::predicates_element + < + index::detail::predicates_find_distance::value, Predicates + > nearest_predicate_access; typedef typename nearest_predicate_access::type nearest_predicate_type; typedef typename indexable_type::type indexable_type; @@ -298,11 +297,7 @@ private: strategy_type m_strategy; }; -template < - typename MembersHolder, - typename Predicates, - std::size_t DistancePredicateIndex -> +template class distance_query_incremental : public MembersHolder::visitor_const { @@ -319,7 +314,10 @@ public: typedef typename MembersHolder::internal_node internal_node; typedef typename MembersHolder::leaf leaf; - typedef index::detail::predicates_element nearest_predicate_access; + typedef index::detail::predicates_element + < + index::detail::predicates_find_distance::value, Predicates + > nearest_predicate_access; typedef typename nearest_predicate_access::type nearest_predicate_type; typedef typename indexable_type::type indexable_type; diff --git a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp index 4aa579530..77ce05ce9 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index 5a4941cfb..e0a5e001d 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -1079,17 +1079,9 @@ public: template size_type query(Predicates const& predicates, OutIter out_it) const { - if ( !m_members.root ) - return 0; - - static const std::size_t distance_predicates_count = detail::predicates_count_distance::value; - static const bool is_distance_predicate = 0 < distance_predicates_count; - BOOST_GEOMETRY_STATIC_ASSERT((distance_predicates_count <= 1), - "Only one distance predicate can be passed.", - Predicates); - - return query_dispatch(predicates, out_it, - std::integral_constant()); + return m_members.root + ? query_dispatch(predicates, out_it) + : 0; } /*! @@ -1183,6 +1175,15 @@ public: return const_query_iterator(); } +private: + template + using query_iterator_t = std::conditional_t + < + detail::predicates_count_distance::value == 0, + detail::rtree::iterators::spatial_query_iterator, + detail::rtree::iterators::distance_query_iterator + >; + #ifndef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL private: #endif @@ -1240,38 +1241,15 @@ private: \return The iterator pointing at the begin of the query range. */ template - std::conditional_t - < - detail::predicates_count_distance::value == 0, - detail::rtree::iterators::spatial_query_iterator, - detail::rtree::iterators::distance_query_iterator - < - members_holder, Predicates, - detail::predicates_find_distance::value - > - > - qbegin_(Predicates const& predicates) const + query_iterator_t qbegin_(Predicates const& predicates) const { - static const std::size_t distance_predicates_count = detail::predicates_count_distance::value; - BOOST_GEOMETRY_STATIC_ASSERT((distance_predicates_count <= 1), + BOOST_GEOMETRY_STATIC_ASSERT((detail::predicates_count_distance::value <= 1), "Only one distance predicate can be passed.", Predicates); - typedef std::conditional_t - < - detail::predicates_count_distance::value == 0, - detail::rtree::iterators::spatial_query_iterator, - detail::rtree::iterators::distance_query_iterator - < - members_holder, Predicates, - detail::predicates_find_distance::value - > - > iterator_type; - - if ( !m_members.root ) - return iterator_type(m_members.parameters(), m_members.translator(), predicates); - - return iterator_type(m_members.root, m_members.parameters(), m_members.translator(), predicates); + return m_members.root + ? query_iterator_t(m_members.root, m_members.parameters(), m_members.translator(), predicates) + : query_iterator_t(m_members.parameters(), m_members.translator(), predicates); } /*! @@ -1307,35 +1285,13 @@ private: \return The iterator pointing at the end of the query range. */ template - std::conditional_t - < - detail::predicates_count_distance::value == 0, - detail::rtree::iterators::spatial_query_iterator, - detail::rtree::iterators::distance_query_iterator - < - members_holder, Predicates, - detail::predicates_find_distance::value - > - > - qend_(Predicates const& predicates) const + query_iterator_t qend_(Predicates const& predicates) const { - static const std::size_t distance_predicates_count = detail::predicates_count_distance::value; - BOOST_GEOMETRY_STATIC_ASSERT((distance_predicates_count <= 1), + BOOST_GEOMETRY_STATIC_ASSERT((detail::predicates_count_distance::value <= 1), "Only one distance predicate can be passed.", Predicates); - typedef std::conditional_t - < - detail::predicates_count_distance::value == 0, - detail::rtree::iterators::spatial_query_iterator, - detail::rtree::iterators::distance_query_iterator - < - members_holder, Predicates, - detail::predicates_find_distance::value - > - > iterator_type; - - return iterator_type(m_members.parameters(), m_members.translator(), predicates); + return query_iterator_t(m_members.parameters(), m_members.translator(), predicates); } /*! @@ -1436,10 +1392,9 @@ public: */ const_iterator begin() const { - if ( !m_members.root ) - return const_iterator(); - - return const_iterator(m_members.root); + return m_members.root + ? const_iterator(m_members.root) + : const_iterator(); } /*! @@ -1894,8 +1849,12 @@ private: \par Exception-safety strong */ - template - size_type query_dispatch(Predicates const& predicates, OutIter out_it, std::false_type /*is_distance_predicate*/) const + template + < + typename Predicates, typename OutIter, + std::enable_if_t<(detail::predicates_count_distance::value == 0), int> = 0 + > + size_type query_dispatch(Predicates const& predicates, OutIter out_it) const { detail::rtree::visitors::spatial_query find_v(m_members.parameters(), m_members.translator(), predicates, out_it); @@ -1909,17 +1868,19 @@ private: \par Exception-safety strong */ - template - size_type query_dispatch(Predicates const& predicates, OutIter out_it, std::true_type /*is_distance_predicate*/) const + template + < + typename Predicates, typename OutIter, + std::enable_if_t<(detail::predicates_count_distance::value > 0), int> = 0 + > + size_type query_dispatch(Predicates const& predicates, OutIter out_it) const { - BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist"); + BOOST_GEOMETRY_STATIC_ASSERT((detail::predicates_count_distance::value == 1), + "Only one distance predicate can be passed.", + Predicates); - static const std::size_t distance_predicate_index = detail::predicates_find_distance::value; - detail::rtree::visitors::distance_query< - members_holder, - Predicates, - distance_predicate_index - > distance_v(m_members.parameters(), m_members.translator(), predicates); + detail::rtree::visitors::distance_query + distance_v(m_members.parameters(), m_members.translator(), predicates); return distance_v.apply(m_members.root, out_it); } From 5ceb8a3b2e43eb9749d709b5a918d433edcd2802 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 22 Jul 2021 22:29:02 +0200 Subject: [PATCH 25/74] [index] Rewrite predicate checks in query visitors. --- .../detail/rtree/visitors/distance_query.hpp | 165 ++++++++---------- .../detail/rtree/visitors/spatial_query.hpp | 28 ++- 2 files changed, 81 insertions(+), 112 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp index b7d119f10..43a943e20 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp @@ -84,11 +84,10 @@ public: inline distance_query_result(size_type k) : m_count(k) { - BOOST_GEOMETRY_INDEX_ASSERT(0 < m_count, "Number of neighbors should be greater than 0"); - m_neighbors.reserve(m_count); } + // NOTE: Do not call if max_count() == 0 inline void store(DistanceType const& distance, const Value * value_ptr) { if (m_neighbors.size() < m_count) @@ -109,6 +108,7 @@ public: } } + // NOTE: Do not call if max_count() == 0 inline bool ignore_branch(DistanceType const& distance) const { return m_neighbors.size() == m_count @@ -127,6 +127,11 @@ public: return m_neighbors.size(); } + size_type max_count() const + { + return m_count; + } + private: size_type m_count; neighbors_type m_neighbors; @@ -184,28 +189,29 @@ public: }; inline distance_query(parameters_type const& parameters, translator_type const& translator, Predicates const& pred) - : m_parameters(parameters), m_translator(translator) + : m_tr(translator) , m_pred(pred) , m_result(nearest_predicate_access::get(m_pred).count) , m_strategy(index::detail::get_strategy(parameters)) { - //m_branches.reserve(m_parameters.get_max_elements() * levels_count); ? + //m_branches.reserve(parameters.get_max_elements() * levels_count); ? } template size_type apply(node_pointer root, OutIter out_it) { + if (m_result.max_count() <= 0) + { + return 0; + } + m_level = 1; rtree::apply_visitor(*this, *root); for (;;) { - if (m_branches.empty()) - { - break; - } - - if (m_result.ignore_branch(m_branches.top().distance)) + if (m_branches.empty() + || m_result.ignore_branch(m_branches.top().distance)) { break; } @@ -226,30 +232,18 @@ public: // fill array of nodes meeting predicates for (auto const& p : rtree::elements(n)) { - // if current node meets predicates - // 0 - dummy value - if (! id::predicates_check(m_pred, 0, p.first, m_strategy)) - { - continue; - } + node_distance_type node_distance; // for distance predicate - // calculate node's distance(s) for distance predicate - node_distance_type node_distance; - // if distance isn't ok - move to the next node - if (! calculate_node_distance::apply(predicate(), p.first, - m_strategy, node_distance)) + // if current node meets predicates (0 is dummy value) + if (id::predicates_check(m_pred, 0, p.first, m_strategy) + // and if distance is ok + && calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance) + // and if current node is closer than the furthest neighbor + && ! m_result.ignore_branch(node_distance)) { - continue; + // add current node's data into the list + m_branches.push(branch_data(node_distance, m_level, p.second)); } - - // if current node is further than found neighbors - don't analyze it - if (m_result.ignore_branch(node_distance)) - { - continue; - } - - // add current node's data into the list - m_branches.push(branch_data(node_distance, m_level, p.second)); } } @@ -260,23 +254,16 @@ public: // search leaf for closest value meeting predicates for (auto const& v : rtree::elements(n)) { + value_distance_type value_distance; // for distance predicate + // if value meets predicates - if (! id::predicates_check(m_pred, v, m_translator(v), m_strategy)) + if (id::predicates_check(m_pred, v, m_tr(v), m_strategy) + // and if distance is ok + && calculate_value_distance::apply(predicate(), m_tr(v), m_strategy, value_distance)) { - continue; + // store value + m_result.store(value_distance, boost::addressof(v)); } - - // calculate values distance for distance predicate - value_distance_type value_distance; - // if distance is ok - if (! calculate_value_distance::apply(predicate(), m_translator(v), - m_strategy, value_distance)) - { - continue; - } - - // store value - m_result.store(value_distance, boost::addressof(v)); } } @@ -286,10 +273,10 @@ private: return nearest_predicate_access::get(m_pred); } - parameters_type const& m_parameters; - translator_type const& m_translator; + translator_type const& m_tr; Predicates m_pred; + distance_query_result m_result; priority_queue m_branches; size_type m_level; @@ -340,7 +327,7 @@ public: using neighbors_type = priority_dequeue; inline distance_query_incremental() - : m_translator(nullptr) + : m_tr(nullptr) // , m_pred() , m_neighbors_count(0) , m_neighbor_ptr(nullptr) @@ -348,7 +335,7 @@ public: {} inline distance_query_incremental(parameters_type const& params, translator_type const& translator, Predicates const& pred) - : m_translator(::boost::addressof(translator)) + : m_tr(::boost::addressof(translator)) , m_pred(pred) , m_neighbors_count(0) , m_neighbor_ptr(nullptr) @@ -407,8 +394,7 @@ public: BOOST_GEOMETRY_INDEX_ASSERT(m_neighbors_count + m_neighbors.size() <= max_count(), "unexpected neighbors count"); // if there is enough neighbors and there is no closer branch - if (m_neighbors_count + m_neighbors.size() == max_count() - && (m_neighbors.empty() || m_neighbors.bottom().first <= closest_branch.first)) + if (ignore_branch_or_value(closest_branch.first)) { m_branches.clear(); continue; @@ -444,30 +430,18 @@ public: // fill active branch list array of nodes meeting predicates for (auto const& p : rtree::elements(n)) { - // if current node doesn't meet predicates - // 0 - dummy value - if (! id::predicates_check(m_pred, 0, p.first, m_strategy)) - { - continue; - } + node_distance_type node_distance; // for distance predicate - // calculate node's distance(s) for distance predicate - node_distance_type node_distance; - // if distance isn't ok - if (! calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance)) + // if current node meets predicates (0 is dummy value) + if (id::predicates_check(m_pred, 0, p.first, m_strategy) + // and if distance is ok + && calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance) + // and if current node is closer than the furthest neighbor + && ! ignore_branch_or_value(node_distance)) { - continue; + // add current node into the queue + m_branches.push(std::make_pair(node_distance, p.second)); } - - // if there is enough neighbors and there is no closer branch - if (m_neighbors_count + m_neighbors.size() == max_count() - && (m_neighbors.empty() || m_neighbors.bottom().first <= node_distance)) - { - continue; - } - - // add current node into the queue - m_branches.push(std::make_pair(node_distance, p.second)); } } @@ -481,38 +455,35 @@ public: // search leaf for closest value meeting predicates for (auto const& v : rtree::elements(n)) { - // if value doesn't meet predicates - if (! id::predicates_check(m_pred, v, (*m_translator)(v), m_strategy)) - { - continue; - } - - // calculate values distance for distance predicate - value_distance_type value_distance; - // if distance isn't ok - if (! calculate_value_distance::apply(predicate(), (*m_translator)(v), - m_strategy, value_distance)) - { - continue; - } + value_distance_type value_distance; // for distance predicate - // if there is enough neighbors and there is no closer neighbor - if (m_neighbors_count + m_neighbors.size() == max_count() - && (m_neighbors.empty() || m_neighbors.bottom().first <= value_distance)) + // if value meets predicates + if (id::predicates_check(m_pred, v, (*m_tr)(v), m_strategy) + // and if distance is ok + && calculate_value_distance::apply(predicate(), (*m_tr)(v), m_strategy, value_distance) + // and if current value is closer than the furthest neighbor + && ! ignore_branch_or_value(value_distance)) { - continue; - } + // add current value into the queue + m_neighbors.push(std::make_pair(value_distance, boost::addressof(v))); - // add current value into the queue - m_neighbors.push(std::make_pair(value_distance, boost::addressof(v))); - if (m_neighbors_count + m_neighbors.size() > max_count()) - { - m_neighbors.pop_bottom(); + // remove unneeded value + if (m_neighbors_count + m_neighbors.size() > max_count()) + { + m_neighbors.pop_bottom(); + } } } } private: + template + inline bool ignore_branch_or_value(Distance const& distance) + { + return m_neighbors_count + m_neighbors.size() == max_count() + && (m_neighbors.empty() || m_neighbors.bottom().first <= distance); + } + inline std::size_t max_count() const { return nearest_predicate_access::get(m_pred).count; @@ -523,7 +494,7 @@ private: return nearest_predicate_access::get(m_pred); } - const translator_type * m_translator; + const translator_type * m_tr; Predicates m_pred; diff --git a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp index 77ce05ce9..64d7585bf 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp @@ -39,7 +39,7 @@ struct spatial_query typedef typename allocators_type::size_type size_type; inline spatial_query(parameters_type const& par, translator_type const& t, Predicates const& p, OutIter out_it) - : tr(t), pred(p), out_iter(out_it), found_count(0), strategy(index::detail::get_strategy(par)) + : m_tr(t), m_pred(p), m_out_iter(out_it), m_found_count(0), m_strategy(index::detail::get_strategy(par)) {} size_type apply(node_pointer root) @@ -58,7 +58,7 @@ struct spatial_query rtree::apply_visitor(*this, *ptr); } - return found_count; + return m_found_count; } inline void operator()(internal_node const& n) @@ -68,9 +68,8 @@ struct spatial_query // traverse nodes meeting predicates for (auto const& p : rtree::elements(n)) { - // if node meets predicates - // 0 - dummy value - if (id::predicates_check(pred, 0, p.first, strategy)) + // if node meets predicates (0 is dummy value) + if (id::predicates_check(m_pred, 0, p.first, m_strategy)) { m_internal_stack.push_back(p.second); } @@ -85,27 +84,26 @@ struct spatial_query for (auto const& v : rtree::elements(n)) { // if value meets predicates - if (id::predicates_check(pred, v, tr(v), strategy)) + if (id::predicates_check(m_pred, v, m_tr(v), m_strategy)) { - *out_iter = v; - ++out_iter; - - ++found_count; + *m_out_iter = v; + ++m_out_iter; + ++m_found_count; } } } private: - translator_type const& tr; + translator_type const& m_tr; - Predicates pred; + Predicates m_pred; std::vector m_internal_stack; - OutIter out_iter; - size_type found_count; + OutIter m_out_iter; + size_type m_found_count; - strategy_type strategy; + strategy_type m_strategy; }; template From 640f2ee3b5cb5685dcee474df270c82dab8f85d1 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 29 Jul 2021 22:06:37 +0200 Subject: [PATCH 26/74] [index] Traverse nodes differently in iterative distance query. In iterative distance query prioritize also based on level. This should ensure that leafs are reached asap in case there are many internal nodes with the same distance. Replace apply_visitor with get() after manually checking level. This is the first step to support weak nodes - non-variant nodes without an id stored internally to distinguish between internal nodes and leafs. Restore recursion in spatial query because it is faster and will stay at least for now because during destruction the rtree is traversed as well and manual stack could throw bad_alloc. --- .../index/detail/rtree/query_iterators.hpp | 105 ++---- .../detail/rtree/visitors/distance_query.hpp | 319 +++++++++++------- .../detail/rtree/visitors/spatial_query.hpp | 212 ++++++------ include/boost/geometry/index/rtree.hpp | 13 +- 4 files changed, 337 insertions(+), 312 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/query_iterators.hpp b/include/boost/geometry/index/detail/rtree/query_iterators.hpp index 28b19aed0..4922d06c8 100644 --- a/include/boost/geometry/index/detail/rtree/query_iterators.hpp +++ b/include/boost/geometry/index/detail/rtree/query_iterators.hpp @@ -17,8 +17,6 @@ #include -//#define BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE - namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators { template @@ -65,13 +63,8 @@ struct end_query_iterator template class spatial_query_iterator { - typedef typename MembersHolder::parameters_type parameters_type; - typedef typename MembersHolder::translator_type translator_type; typedef typename MembersHolder::allocators_type allocators_type; - typedef visitors::spatial_query_incremental visitor_type; - typedef typename visitor_type::node_pointer node_pointer; - public: typedef std::forward_iterator_tag iterator_category; typedef typename MembersHolder::value_type value_type; @@ -79,32 +72,31 @@ public: typedef typename allocators_type::difference_type difference_type; typedef typename allocators_type::const_pointer pointer; - inline spatial_query_iterator() + spatial_query_iterator() = default; + + explicit spatial_query_iterator(Predicates const& pred) + : m_impl(pred) {} - inline spatial_query_iterator(parameters_type const& par, translator_type const& t, Predicates const& p) - : m_visitor(par, t, p) - {} - - inline spatial_query_iterator(node_pointer root, parameters_type const& par, translator_type const& t, Predicates const& p) - : m_visitor(par, t, p) + spatial_query_iterator(MembersHolder const& members, Predicates const& pred) + : m_impl(members, pred) { - m_visitor.initialize(root); + m_impl.initialize(members); } reference operator*() const { - return m_visitor.dereference(); + return m_impl.dereference(); } const value_type * operator->() const { - return boost::addressof(m_visitor.dereference()); + return boost::addressof(m_impl.dereference()); } spatial_query_iterator & operator++() { - m_visitor.increment(); + m_impl.increment(); return *this; } @@ -117,33 +109,28 @@ public: friend bool operator==(spatial_query_iterator const& l, spatial_query_iterator const& r) { - return l.m_visitor == r.m_visitor; + return l.m_impl == r.m_impl; } friend bool operator==(spatial_query_iterator const& l, end_query_iterator const& /*r*/) { - return l.m_visitor.is_end(); + return l.m_impl.is_end(); } friend bool operator==(end_query_iterator const& /*l*/, spatial_query_iterator const& r) { - return r.m_visitor.is_end(); + return r.m_impl.is_end(); } private: - visitor_type m_visitor; + visitors::spatial_query_incremental m_impl; }; template class distance_query_iterator { - typedef typename MembersHolder::parameters_type parameters_type; - typedef typename MembersHolder::translator_type translator_type; typedef typename MembersHolder::allocators_type allocators_type; - typedef visitors::distance_query_incremental visitor_type; - typedef typename visitor_type::node_pointer node_pointer; - public: typedef std::forward_iterator_tag iterator_category; typedef typename MembersHolder::value_type value_type; @@ -151,32 +138,31 @@ public: typedef typename allocators_type::difference_type difference_type; typedef typename allocators_type::const_pointer pointer; - inline distance_query_iterator() + distance_query_iterator() = default; + + explicit distance_query_iterator(Predicates const& pred) + : m_impl(pred) {} - inline distance_query_iterator(parameters_type const& par, translator_type const& t, Predicates const& p) - : m_visitor(par, t, p) - {} - - inline distance_query_iterator(node_pointer root, parameters_type const& par, translator_type const& t, Predicates const& p) - : m_visitor(par, t, p) + distance_query_iterator(MembersHolder const& members, Predicates const& pred) + : m_impl(members, pred) { - m_visitor.initialize(root); + m_impl.initialize(members); } reference operator*() const { - return m_visitor.dereference(); + return m_impl.dereference(); } const value_type * operator->() const { - return boost::addressof(m_visitor.dereference()); + return boost::addressof(m_impl.dereference()); } distance_query_iterator & operator++() { - m_visitor.increment(); + m_impl.increment(); return *this; } @@ -189,21 +175,21 @@ public: friend bool operator==(distance_query_iterator const& l, distance_query_iterator const& r) { - return l.m_visitor == r.m_visitor; + return l.m_impl == r.m_impl; } friend bool operator==(distance_query_iterator const& l, end_query_iterator const& /*r*/) { - return l.m_visitor.is_end(); + return l.m_impl.is_end(); } friend bool operator==(end_query_iterator const& /*l*/, distance_query_iterator const& r) { - return r.m_visitor.is_end(); + return r.m_impl.is_end(); } private: - visitor_type m_visitor; + visitors::distance_query_incremental m_impl; }; @@ -280,8 +266,7 @@ public: typedef typename Allocators::difference_type difference_type; typedef typename Allocators::const_pointer pointer; - query_iterator() - {} + query_iterator() = default; template query_iterator(It const& it) @@ -296,7 +281,6 @@ public: : m_ptr(o.m_ptr.get() ? o.m_ptr->clone() : 0) {} -#ifndef BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE query_iterator & operator=(query_iterator const& o) { if ( this != boost::addressof(o) ) @@ -305,12 +289,13 @@ public: } return *this; } -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + query_iterator(query_iterator && o) : m_ptr(0) { m_ptr.swap(o.m_ptr); } + query_iterator & operator=(query_iterator && o) { if ( this != boost::addressof(o) ) @@ -320,34 +305,6 @@ public: } return *this; } -#endif -#else // !BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE -private: - BOOST_COPYABLE_AND_MOVABLE(query_iterator) -public: - query_iterator & operator=(BOOST_COPY_ASSIGN_REF(query_iterator) o) - { - if ( this != boost::addressof(o) ) - { - m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0); - } - return *this; - } - query_iterator(BOOST_RV_REF(query_iterator) o) - : m_ptr(0) - { - m_ptr.swap(o.m_ptr); - } - query_iterator & operator=(BOOST_RV_REF(query_iterator) o) - { - if ( this != boost::addressof(o) ) - { - m_ptr.swap(o.m_ptr); - o.m_ptr.reset(); - } - return *this; - } -#endif // BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE reference operator*() const { diff --git a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp index 43a943e20..9b2aad3f1 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp @@ -73,6 +73,15 @@ struct priority_queue : std::priority_queue, Comp> } }; +struct branch_data_comp +{ + template + bool operator()(BranchData const& b1, BranchData const& b2) const + { + return b1.distance > b2.distance || (b1.distance == b2.distance && b1.reverse_level > b2.reverse_level); + } +}; + template class distance_query_result { @@ -139,14 +148,11 @@ private: template class distance_query - : public MembersHolder::visitor_const { -public: typedef typename MembersHolder::value_type value_type; typedef typename MembersHolder::box_type box_type; typedef typename MembersHolder::parameters_type parameters_type; typedef typename MembersHolder::translator_type translator_type; - typedef typename MembersHolder::allocators_type allocators_type; typedef typename index::detail::strategy_type::type strategy_type; @@ -166,129 +172,160 @@ public: typedef typename calculate_value_distance::result_type value_distance_type; typedef typename calculate_node_distance::result_type node_distance_type; - typedef typename allocators_type::size_type size_type; - typedef typename allocators_type::node_pointer node_pointer; + typedef typename MembersHolder::size_type size_type; + typedef typename MembersHolder::node_pointer node_pointer; + + using neighbor_data = std::pair; + using neighbors_type = std::vector; struct branch_data { - branch_data(node_distance_type d, size_type l, node_pointer p) - : distance(d), level(l), ptr(p) + branch_data(node_distance_type d, size_type rl, node_pointer p) + : distance(d), reverse_level(rl), ptr(p) {} node_distance_type distance; - size_type level; + size_type reverse_level; node_pointer ptr; }; + using branches_type = priority_queue; - struct branch_data_comp - { - bool operator()(branch_data const& b1, branch_data const& b2) const - { - return b1.distance > b2.distance || (b1.distance == b2.distance && b1.level < b2.level); - } - }; - - inline distance_query(parameters_type const& parameters, translator_type const& translator, Predicates const& pred) - : m_tr(translator) +public: + distance_query(MembersHolder const& members, Predicates const& pred) + : m_tr(members.translator()) + , m_strategy(index::detail::get_strategy(members.parameters())) , m_pred(pred) - , m_result(nearest_predicate_access::get(m_pred).count) - , m_strategy(index::detail::get_strategy(parameters)) { - //m_branches.reserve(parameters.get_max_elements() * levels_count); ? + m_neighbors.reserve((std::min)(members.values_count, size_type(max_count()))); + //m_branches.reserve(members.parameters().get_min_elements() * members.leafs_level); ? + // min, max or average? } template - size_type apply(node_pointer root, OutIter out_it) + size_type apply(MembersHolder const& members, OutIter out_it) { - if (m_result.max_count() <= 0) + return apply(members.root, members.leafs_level, out_it); + } + +private: + template + size_type apply(node_pointer ptr, size_type reverse_level, OutIter out_it) + { + namespace id = index::detail; + + if (max_count() <= 0) { return 0; } - m_level = 1; - rtree::apply_visitor(*this, *root); - for (;;) { + if (reverse_level > 0) + { + internal_node& n = rtree::get(*ptr); + // fill array of nodes meeting predicates + for (auto const& p : rtree::elements(n)) + { + node_distance_type node_distance; // for distance predicate + + // if current node meets predicates (0 is dummy value) + if (id::predicates_check(m_pred, 0, p.first, m_strategy) + // and if distance is ok + && calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance) + // and if current node is closer than the furthest neighbor + && ! ignore_branch(node_distance)) + { + // add current node's data into the list + m_branches.push(branch_data(node_distance, reverse_level - 1, p.second)); + } + } + } + else + { + leaf& n = rtree::get(*ptr); + // search leaf for closest value meeting predicates + for (auto const& v : rtree::elements(n)) + { + value_distance_type value_distance; // for distance predicate + + // if value meets predicates + if (id::predicates_check(m_pred, v, m_tr(v), m_strategy) + // and if distance is ok + && calculate_value_distance::apply(predicate(), m_tr(v), m_strategy, value_distance)) + { + // store value + store_value(value_distance, boost::addressof(v)); + } + } + } + if (m_branches.empty() - || m_result.ignore_branch(m_branches.top().distance)) + || ignore_branch(m_branches.top().distance)) { break; } - node_pointer ptr = m_branches.top().ptr; - m_level = m_branches.top().level + 1; + ptr = m_branches.top().ptr; + reverse_level = m_branches.top().reverse_level; m_branches.pop(); - rtree::apply_visitor(*this, *ptr); } - return m_result.finish(out_it); + for (auto const& p : m_neighbors) + { + *out_it = *(p.second); + ++out_it; + } + + return m_neighbors.size(); } - inline void operator()(internal_node const& n) + bool ignore_branch(node_distance_type const& node_distance) const { - namespace id = index::detail; + return m_neighbors.size() == max_count() + && m_neighbors.front().first <= node_distance; + } - // fill array of nodes meeting predicates - for (auto const& p : rtree::elements(n)) + void store_value(value_distance_type value_distance, const value_type * value_ptr) + { + if (m_neighbors.size() < max_count()) { - node_distance_type node_distance; // for distance predicate + m_neighbors.push_back(std::make_pair(value_distance, value_ptr)); - // if current node meets predicates (0 is dummy value) - if (id::predicates_check(m_pred, 0, p.first, m_strategy) - // and if distance is ok - && calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance) - // and if current node is closer than the furthest neighbor - && ! m_result.ignore_branch(node_distance)) + if (m_neighbors.size() == max_count()) { - // add current node's data into the list - m_branches.push(branch_data(node_distance, m_level, p.second)); + std::make_heap(m_neighbors.begin(), m_neighbors.end(), pair_first_less()); } } - } - - inline void operator()(leaf const& n) - { - namespace id = index::detail; - - // search leaf for closest value meeting predicates - for (auto const& v : rtree::elements(n)) + else if (value_distance < m_neighbors.front().first) { - value_distance_type value_distance; // for distance predicate - - // if value meets predicates - if (id::predicates_check(m_pred, v, m_tr(v), m_strategy) - // and if distance is ok - && calculate_value_distance::apply(predicate(), m_tr(v), m_strategy, value_distance)) - { - // store value - m_result.store(value_distance, boost::addressof(v)); - } + std::pop_heap(m_neighbors.begin(), m_neighbors.end(), pair_first_less()); + m_neighbors.back() = std::make_pair(value_distance, value_ptr); + std::push_heap(m_neighbors.begin(), m_neighbors.end(), pair_first_less()); } } -private: + std::size_t max_count() const + { + return nearest_predicate_access::get(m_pred).count; + } + nearest_predicate_type const& predicate() const { return nearest_predicate_access::get(m_pred); } translator_type const& m_tr; - - Predicates m_pred; - - distance_query_result m_result; - priority_queue m_branches; - size_type m_level; - strategy_type m_strategy; + + Predicates const& m_pred; + + branches_type m_branches; + neighbors_type m_neighbors; }; template class distance_query_incremental - : public MembersHolder::visitor_const { -public: typedef typename MembersHolder::value_type value_type; typedef typename MembersHolder::box_type box_type; typedef typename MembersHolder::parameters_type parameters_type; @@ -321,25 +358,44 @@ public: typedef typename internal_elements::const_iterator internal_iterator; typedef typename rtree::elements_type::type leaf_elements; - using branch_data = std::pair; - using branches_type = priority_queue; using neighbor_data = std::pair; using neighbors_type = priority_dequeue; + struct branch_data + { + branch_data(node_distance_type d, size_type rl, node_pointer p) + : distance(d), reverse_level(rl), ptr(p) + {} + + node_distance_type distance; + size_type reverse_level; + node_pointer ptr; + }; + using branches_type = priority_queue; + +public: inline distance_query_incremental() : m_tr(nullptr) +// , m_strategy() // , m_pred() , m_neighbors_count(0) , m_neighbor_ptr(nullptr) -// , m_strategy_type() {} - inline distance_query_incremental(parameters_type const& params, translator_type const& translator, Predicates const& pred) - : m_tr(::boost::addressof(translator)) + inline distance_query_incremental(Predicates const& pred) + : m_tr(nullptr) +// , m_strategy() , m_pred(pred) , m_neighbors_count(0) - , m_neighbor_ptr(nullptr) - , m_strategy(index::detail::get_strategy(params)) + , m_neighbor_ptr(nullptr) + {} + + inline distance_query_incremental(MembersHolder const& members, Predicates const& pred) + : m_tr(::boost::addressof(members.translator())) + , m_strategy(index::detail::get_strategy(members.parameters())) + , m_pred(pred) + , m_neighbors_count(0) + , m_neighbor_ptr(nullptr) {} const_reference dereference() const @@ -347,11 +403,11 @@ public: return *m_neighbor_ptr; } - void initialize(node_pointer root) + void initialize(MembersHolder const& members) { if (0 < max_count()) { - rtree::apply_visitor(*this, *root); + apply(members.root, members.leafs_level); increment(); } } @@ -383,7 +439,7 @@ public: branch_data const& closest_branch = m_branches.top(); // if next neighbor is closer or as close as the closest branch, set next neighbor - if (! m_neighbors.empty() && m_neighbors.top().first <= closest_branch.first ) + if (! m_neighbors.empty() && m_neighbors.top().first <= closest_branch.distance ) { m_neighbor_ptr = m_neighbors.top().second; ++m_neighbors_count; @@ -394,17 +450,18 @@ public: BOOST_GEOMETRY_INDEX_ASSERT(m_neighbors_count + m_neighbors.size() <= max_count(), "unexpected neighbors count"); // if there is enough neighbors and there is no closer branch - if (ignore_branch_or_value(closest_branch.first)) + if (ignore_branch_or_value(closest_branch.distance)) { m_branches.clear(); continue; } else { - node_pointer ptr = closest_branch.second; + node_pointer ptr = closest_branch.ptr; + size_type reverse_level = closest_branch.reverse_level; m_branches.pop(); - rtree::apply_visitor(*this, *ptr); + apply(ptr, reverse_level); } } } @@ -420,71 +477,72 @@ public: return l.m_neighbors_count == r.m_neighbors_count; } - // Put node's elements into the list of active branches if those elements meets predicates - // and distance predicates(currently not used) - // and aren't further than found neighbours (if there is enough neighbours) - inline void operator()(internal_node const& n) +private: + void apply(node_pointer ptr, size_type reverse_level) { namespace id = index::detail; - - // fill active branch list array of nodes meeting predicates - for (auto const& p : rtree::elements(n)) + // Put node's elements into the list of active branches if those elements meets predicates + // and distance predicates(currently not used) + // and aren't further than found neighbours (if there is enough neighbours) + if (reverse_level > 0) { - node_distance_type node_distance; // for distance predicate - - // if current node meets predicates (0 is dummy value) - if (id::predicates_check(m_pred, 0, p.first, m_strategy) - // and if distance is ok - && calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance) - // and if current node is closer than the furthest neighbor - && ! ignore_branch_or_value(node_distance)) + internal_node& n = rtree::get(*ptr); + // fill active branch list array of nodes meeting predicates + for (auto const& p : rtree::elements(n)) { - // add current node into the queue - m_branches.push(std::make_pair(node_distance, p.second)); + node_distance_type node_distance; // for distance predicate + + // if current node meets predicates (0 is dummy value) + if (id::predicates_check(m_pred, 0, p.first, m_strategy) + // and if distance is ok + && calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance) + // and if current node is closer than the furthest neighbor + && ! ignore_branch_or_value(node_distance)) + { + // add current node into the queue + m_branches.push(branch_data(node_distance, reverse_level - 1, p.second)); + } } } - } - - // Put values into the list of neighbours if those values meets predicates - // and distance predicates(currently not used) - // and aren't further than already found neighbours (if there is enough neighbours) - inline void operator()(leaf const& n) - { - namespace id = index::detail; - - // search leaf for closest value meeting predicates - for (auto const& v : rtree::elements(n)) + // Put values into the list of neighbours if those values meets predicates + // and distance predicates(currently not used) + // and aren't further than already found neighbours (if there is enough neighbours) + else { - value_distance_type value_distance; // for distance predicate - - // if value meets predicates - if (id::predicates_check(m_pred, v, (*m_tr)(v), m_strategy) - // and if distance is ok - && calculate_value_distance::apply(predicate(), (*m_tr)(v), m_strategy, value_distance) - // and if current value is closer than the furthest neighbor - && ! ignore_branch_or_value(value_distance)) + leaf& n = rtree::get(*ptr); + // search leaf for closest value meeting predicates + for (auto const& v : rtree::elements(n)) { - // add current value into the queue - m_neighbors.push(std::make_pair(value_distance, boost::addressof(v))); + value_distance_type value_distance; // for distance predicate - // remove unneeded value - if (m_neighbors_count + m_neighbors.size() > max_count()) + // if value meets predicates + if (id::predicates_check(m_pred, v, (*m_tr)(v), m_strategy) + // and if distance is ok + && calculate_value_distance::apply(predicate(), (*m_tr)(v), m_strategy, value_distance) + // and if current value is closer than the furthest neighbor + && ! ignore_branch_or_value(value_distance)) { - m_neighbors.pop_bottom(); + // add current value into the queue + m_neighbors.push(std::make_pair(value_distance, boost::addressof(v))); + + // remove unneeded value + if (m_neighbors_count + m_neighbors.size() > max_count()) + { + m_neighbors.pop_bottom(); + } } } } } -private: template - inline bool ignore_branch_or_value(Distance const& distance) + bool ignore_branch_or_value(Distance const& distance) { return m_neighbors_count + m_neighbors.size() == max_count() && (m_neighbors.empty() || m_neighbors.bottom().first <= distance); } - inline std::size_t max_count() const + std::size_t max_count() const { return nearest_predicate_access::get(m_pred).count; } @@ -495,6 +553,7 @@ private: } const translator_type * m_tr; + strategy_type m_strategy; Predicates m_pred; @@ -502,8 +561,6 @@ private: neighbors_type m_neighbors; size_type m_neighbors_count; const value_type * m_neighbor_ptr; - - strategy_type m_strategy; }; }}} // namespace detail::rtree::visitors diff --git a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp index 64d7585bf..855acab0b 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp @@ -23,7 +23,6 @@ namespace detail { namespace rtree { namespace visitors { template struct spatial_query - : public MembersHolder::visitor_const { typedef typename MembersHolder::parameters_type parameters_type; typedef typename MembersHolder::translator_type translator_type; @@ -38,77 +37,66 @@ struct spatial_query typedef typename allocators_type::node_pointer node_pointer; typedef typename allocators_type::size_type size_type; - inline spatial_query(parameters_type const& par, translator_type const& t, Predicates const& p, OutIter out_it) - : m_tr(t), m_pred(p), m_out_iter(out_it), m_found_count(0), m_strategy(index::detail::get_strategy(par)) + spatial_query(MembersHolder const& members, Predicates const& p, OutIter out_it) + : m_tr(members.translator()) + , m_strategy(index::detail::get_strategy(members.parameters())) + , m_pred(p) + , m_out_iter(out_it) + , m_found_count(0) {} - size_type apply(node_pointer root) + size_type apply(node_pointer ptr, size_type reverse_level) { - rtree::apply_visitor(*this, *root); - - for (;;) + namespace id = index::detail; + if (reverse_level > 0) { - if (m_internal_stack.empty()) + internal_node& n = rtree::get(*ptr); + // traverse nodes meeting predicates + for (auto const& p : rtree::elements(n)) { - break; + // if node meets predicates (0 is dummy value) + if (id::predicates_check(m_pred, 0, p.first, m_strategy)) + { + apply(p.second, reverse_level - 1); + } + } + } + else + { + leaf& n = rtree::get(*ptr); + // get all values meeting predicates + for (auto const& v : rtree::elements(n)) + { + // if value meets predicates + if (id::predicates_check(m_pred, v, m_tr(v), m_strategy)) + { + *m_out_iter = v; + ++m_out_iter; + ++m_found_count; + } } - - node_pointer ptr = m_internal_stack.back(); - m_internal_stack.pop_back(); - rtree::apply_visitor(*this, *ptr); } return m_found_count; } - inline void operator()(internal_node const& n) + size_type apply(MembersHolder const& members) { - namespace id = index::detail; - - // traverse nodes meeting predicates - for (auto const& p : rtree::elements(n)) - { - // if node meets predicates (0 is dummy value) - if (id::predicates_check(m_pred, 0, p.first, m_strategy)) - { - m_internal_stack.push_back(p.second); - } - } - } - - inline void operator()(leaf const& n) - { - namespace id = index::detail; - - // get all values meeting predicates - for (auto const& v : rtree::elements(n)) - { - // if value meets predicates - if (id::predicates_check(m_pred, v, m_tr(v), m_strategy)) - { - *m_out_iter = v; - ++m_out_iter; - ++m_found_count; - } - } + return apply(members.root, members.leafs_level); } private: translator_type const& m_tr; - - Predicates m_pred; - - std::vector m_internal_stack; - - OutIter m_out_iter; - size_type m_found_count; - strategy_type m_strategy; + + Predicates const& m_pred; + OutIter m_out_iter; + + size_type m_found_count; }; template class spatial_query_incremental - : public MembersHolder::visitor_const { typedef typename MembersHolder::value_type value_type; typedef typename MembersHolder::parameters_type parameters_type; @@ -117,7 +105,6 @@ class spatial_query_incremental typedef typename index::detail::strategy_type::type strategy_type; -public: typedef typename MembersHolder::node node; typedef typename MembersHolder::internal_node internal_node; typedef typename MembersHolder::leaf leaf; @@ -130,35 +117,40 @@ public: typedef typename rtree::elements_type::type leaf_elements; typedef typename rtree::elements_type::type::const_iterator leaf_iterator; - inline spatial_query_incremental() - : m_translator(NULL) -// , m_pred() - , m_values(NULL) - , m_current() + struct internal_data + { + internal_data(internal_iterator f, internal_iterator l, size_type rl) + : first(f), last(l), reverse_level(rl) + {} + internal_iterator first; + internal_iterator last; + size_type reverse_level; + }; + +public: + spatial_query_incremental() + : m_translator(nullptr) // , m_strategy() - {} - - inline spatial_query_incremental(parameters_type const& params, translator_type const& t, Predicates const& p) - : m_translator(::boost::addressof(t)) - , m_pred(p) - , m_values(NULL) +// , m_pred() + , m_values(nullptr) , m_current() - , m_strategy(index::detail::get_strategy(params)) {} - inline void operator()(internal_node const& n) - { - typedef typename rtree::elements_type::type elements_type; - elements_type const& elements = rtree::elements(n); + spatial_query_incremental(Predicates const& p) + : m_translator(nullptr) +// , m_strategy() + , m_pred(p) + , m_values(nullptr) + , m_current() + {} - m_internal_stack.push_back(std::make_pair(elements.begin(), elements.end())); - } - - inline void operator()(leaf const& n) - { - m_values = ::boost::addressof(rtree::elements(n)); - m_current = rtree::elements(n).begin(); - } + spatial_query_incremental(MembersHolder const& members, Predicates const& p) + : m_translator(::boost::addressof(members.translator())) + , m_strategy(index::detail::get_strategy(members.parameters())) + , m_pred(p) + , m_values(nullptr) + , m_current() + {} const_reference dereference() const { @@ -166,9 +158,9 @@ public: return *m_current; } - void initialize(node_pointer root) + void initialize(MembersHolder const& members) { - rtree::apply_visitor(*this, *root); + apply(members.root, members.leafs_level); search_value(); } @@ -178,6 +170,35 @@ public: search_value(); } + bool is_end() const + { + return 0 == m_values; + } + + friend bool operator==(spatial_query_incremental const& l, spatial_query_incremental const& r) + { + return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current); + } + +private: + void apply(node_pointer ptr, size_type reverse_level) + { + namespace id = index::detail; + + if (reverse_level > 0) + { + internal_node& n = rtree::get(*ptr); + auto const& elements = rtree::elements(n); + m_internal_stack.push_back(internal_data(elements.begin(), elements.end(), reverse_level - 1)); + } + else + { + leaf& n = rtree::get(*ptr); + m_values = ::boost::addressof(rtree::elements(n)); + m_current = rtree::elements(n).begin(); + } + } + void search_value() { namespace id = index::detail; @@ -207,49 +228,40 @@ public: else { // return if there is no more nodes to traverse - if ( m_internal_stack.empty() ) + if (m_internal_stack.empty()) + { return; + } - // no more children in current node, remove it from stack - if ( m_internal_stack.back().first == m_internal_stack.back().second ) + internal_data& current_data = m_internal_stack.back(); + + // no more children in current node, remove it from stack + if (current_data.first == current_data.last) { m_internal_stack.pop_back(); continue; } - internal_iterator it = m_internal_stack.back().first; - ++m_internal_stack.back().first; + internal_iterator it = current_data.first; + ++current_data.first; // next node is found, push it to the stack if (id::predicates_check(m_pred, 0, it->first, m_strategy)) { - rtree::apply_visitor(*this, *(it->second)); + apply(it->second, current_data.reverse_level); } } } } - - bool is_end() const - { - return 0 == m_values; - } - - friend bool operator==(spatial_query_incremental const& l, spatial_query_incremental const& r) - { - return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current ); - } - -private: - + const translator_type * m_translator; + strategy_type m_strategy; Predicates m_pred; - std::vector< std::pair > m_internal_stack; + std::vector m_internal_stack; const leaf_elements * m_values; leaf_iterator m_current; - - strategy_type m_strategy; }; }}} // namespace detail::rtree::visitors diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index e0a5e001d..af3b6f4ee 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -1248,8 +1248,8 @@ private: Predicates); return m_members.root - ? query_iterator_t(m_members.root, m_members.parameters(), m_members.translator(), predicates) - : query_iterator_t(m_members.parameters(), m_members.translator(), predicates); + ? query_iterator_t(m_members, predicates) + : query_iterator_t(predicates); } /*! @@ -1857,9 +1857,8 @@ private: size_type query_dispatch(Predicates const& predicates, OutIter out_it) const { detail::rtree::visitors::spatial_query - find_v(m_members.parameters(), m_members.translator(), predicates, out_it); - - return find_v.apply(m_members.root); + query(m_members, predicates, out_it); + return query.apply(m_members); } /*! @@ -1880,9 +1879,9 @@ private: Predicates); detail::rtree::visitors::distance_query - distance_v(m_members.parameters(), m_members.translator(), predicates); + distance_v(m_members, predicates); - return distance_v.apply(m_members.root, out_it); + return distance_v.apply(m_members, out_it); } /*! From 5cc1f9019e3b001ef1529a8eb00f6c76e178a589 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 30 Jul 2021 20:44:13 +0200 Subject: [PATCH 27/74] [index] Refactor minmax heap WRT coding guidelines. --- .../geometry/index/detail/minmax_heap.hpp | 58 ++++++++++++++----- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/include/boost/geometry/index/detail/minmax_heap.hpp b/include/boost/geometry/index/detail/minmax_heap.hpp index 18b44d918..1b95f77ea 100644 --- a/include/boost/geometry/index/detail/minmax_heap.hpp +++ b/include/boost/geometry/index/detail/minmax_heap.hpp @@ -45,8 +45,7 @@ inline int level(T i) { ++i; int r = 0; - while (i >>= 1) - ++r; + while (i >>= 1) { ++r; } return r; } @@ -74,10 +73,8 @@ inline int level(T i) #ifdef _WIN64 _BitScanReverse64(&r, (unsigned long long)(i + 1)); #else - if (_BitScanReverse(&r, (unsigned long)((i + 1) >> 32))) - r += 32; - else - _BitScanReverse(&r, (unsigned long)(i + 1)); + if (_BitScanReverse(&r, (unsigned long)((i + 1) >> 32))) { r += 32; } + else { _BitScanReverse(&r, (unsigned long)(i + 1)); } #endif return int(r); } @@ -157,7 +154,9 @@ inline void push_heap2(It first, diff_t c, val_t val, Compare comp) { diff_t const g = (c - 3) >> 2; // grandparent index if (! Call()(comp, val, *(first + g))) + { break; + } *(first + c) = std::move(*(first + g)); c = g; } @@ -175,7 +174,9 @@ inline void push_heap1(It first, diff_t c, val_t val, Compare comp) return push_heap2(first, p, std::move(val), comp); } else + { return push_heap2(first, c, std::move(val), comp); + } } template @@ -183,14 +184,20 @@ inline void push_heap(It first, It last, Compare comp) { diff_t const size = last - first; if (size < 2) + { return; + } diff_t c = size - 1; // back index val_t val = std::move(*(first + c)); if (level(c) % 2 == 0) // is min level + { push_heap1(first, c, std::move(val), comp); + } else + { push_heap1(first, c, std::move(val), comp); + } } @@ -208,8 +215,12 @@ inline diff_t pick_grandchild4(It first, diff_t f, Compare comp) //{ // diff_t m = f; // for (++f; f != l; ++f) +// { // if (Call()(comp, *(first + f), *(first + m))) +// { // m = f; +// } +// } // return m; //} @@ -225,7 +236,9 @@ inline void pop_heap1(It first, diff_t p, diff_t size, val_t val, Co diff_t const m = pick_grandchild4(first, ll, comp); if (! Call()(comp, *(first + m), val)) + { break; + } *(first + p) = std::move(*(first + m)); @@ -294,7 +307,9 @@ inline void pop_heap(It first, It el, It last, Compare comp) { diff_t size = last - first; if (size < 2) + { return; + } --last; val_t val = std::move(*last); @@ -305,9 +320,13 @@ inline void pop_heap(It first, It el, It last, Compare comp) diff_t p = el - first; if (level(p) % 2 == 0) // is min level + { pop_heap1(first, p, size, std::move(val), comp); + } else + { pop_heap1(first, p, size, std::move(val), comp); + } } template @@ -316,7 +335,10 @@ inline void make_heap(It first, It last, Compare comp) diff_t size = last - first; diff_t p = size / 2; if (p <= 0) + { return; + } + int level_p = level(p - 1); diff_t level_f = (diff_t(1) << level_p) - 1; while (p > 0) @@ -324,9 +346,14 @@ inline void make_heap(It first, It last, Compare comp) --p; val_t val = std::move(*(first + p)); if (level_p % 2 == 0) // is min level + { pop_heap1(first, p, size, std::move(val), comp); + } else + { pop_heap1(first, p, size, std::move(val), comp); + } + if (p == level_f) { --level_p; @@ -353,12 +380,16 @@ inline bool is_heap(It first, It last, Compare comp) if (is_min_level) { if (Call()(comp, *(first + p), *(first + i))) + { return false; + } } else { if (Call()(comp, *(first + i), *(first + p))) + { return false; + } } if (i >= 3) @@ -367,12 +398,16 @@ inline bool is_heap(It first, It last, Compare comp) if (is_min_level) { if (Call()(comp, *(first + i), *(first + g))) + { return false; + } } else { if (Call()(comp, *(first + g), *(first + i))) + { return false; + } } } } @@ -383,14 +418,9 @@ template inline It bottom_heap(It first, It last, Compare comp) { diff_t const size = last - first; - if (size <= 1) - return first; - else if (size == 2) - return (first + 1); - else - return Call()(comp, *(first + 1), *(first + 2)) - ? (first + 2) - : (first + 1); + return size <= 1 ? first : + size == 2 ? (first + 1) : + Call()(comp, *(first + 1), *(first + 2)) ? (first + 2) : (first + 1); } } // namespace minmax_heap_detail From 135b9264fda22ea29aa92207f7e62d698f273c9c Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 2 Aug 2021 16:49:37 +0200 Subject: [PATCH 28/74] [test] Fix test case in sort_by_side and gcc variadic macros compilation error. --- test/algorithms/overlay/sort_by_side.cpp | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/algorithms/overlay/sort_by_side.cpp b/test/algorithms/overlay/sort_by_side.cpp index c8ecc6b97..5776d7040 100644 --- a/test/algorithms/overlay/sort_by_side.cpp +++ b/test/algorithms/overlay/sort_by_side.cpp @@ -217,11 +217,11 @@ void test_sort_by_side(std::string const& case_id, // Define two small macro's to avoid repetitions of testcases/names etc -#define TEST_INT(caseid, exp, ...) { (test_sort_by_side) \ - ( #caseid "_int", caseid[0], caseid[1], exp, __VA_ARGS__); } +#define TEST_INTER(caseid, ...) { (test_sort_by_side) \ + ( #caseid "_inter", caseid[0], caseid[1], __VA_ARGS__); } -#define TEST_UNION(caseid, exp, ...) { (test_sort_by_side) \ - ( #caseid "_union", caseid[0], caseid[1], exp, __VA_ARGS__); } +#define TEST_UNION(caseid, ...) { (test_sort_by_side) \ + ( #caseid "_union", caseid[0], caseid[1], __VA_ARGS__); } template void test_all() @@ -232,15 +232,15 @@ void test_all() // Selection of test cases having only one cluster - TEST_INT(case_64_multi, {1}); - TEST_INT(case_72_multi, {3}); - TEST_INT(case_107_multi, {2}); - TEST_INT(case_123_multi, {3}); - TEST_INT(case_124_multi, {3}); - TEST_INT(case_recursive_boxes_10, {2}); - TEST_INT(case_recursive_boxes_20, {2}); - TEST_INT(case_recursive_boxes_21, {2}); - TEST_INT(case_recursive_boxes_22, {0}); + TEST_INTER(case_64_multi, {1}); + TEST_INTER(case_72_multi, {3}); + TEST_INTER(case_107_multi, {2}); + TEST_INTER(case_123_multi, {3}); + TEST_INTER(case_124_multi, {3}); + TEST_INTER(case_recursive_boxes_10, {2}); + TEST_INTER(case_recursive_boxes_20, {2}); + TEST_INTER(case_recursive_boxes_21, {1}); + TEST_INTER(case_recursive_boxes_22, {0}); TEST_UNION(case_recursive_boxes_46, {2, 1, 2, 1, 1, 2, 1}); From eb617fa1c814b7428cee47d08e8d70724ec9a9aa Mon Sep 17 00:00:00 2001 From: Nicholas Devenish Date: Tue, 3 Aug 2021 11:11:25 +0100 Subject: [PATCH 29/74] Fix error checking for failure type in example validity_failure_type is an enum, not a bitflag. Correct example code that looked like it was trying to treat it as a bitflag, but instead assumed that any failure was fixable. --- doc/src/examples/algorithms/is_valid_failure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/examples/algorithms/is_valid_failure.cpp b/doc/src/examples/algorithms/is_valid_failure.cpp index f566e23a2..9569ba6ad 100644 --- a/doc/src/examples/algorithms/is_valid_failure.cpp +++ b/doc/src/examples/algorithms/is_valid_failure.cpp @@ -32,7 +32,7 @@ int main() // if the invalidity is only due to lack of closing points and/or wrongly oriented rings, then bg::correct can fix it bool could_be_fixed = (failure == boost::geometry::failure_not_closed - || boost::geometry::failure_wrong_orientation); + || failure == boost::geometry::failure_wrong_orientation); std::cout << "is valid? " << (valid ? "yes" : "no") << std::endl; if (! valid) { From 1030bd0d70168d1522a0e3dd80ff4287e88cd9c8 Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 28 Jul 2021 15:41:13 +0200 Subject: [PATCH 30/74] [test] add cases for issues #690 #875 #876 --- test/algorithms/check_validity.hpp | 44 ++++++++++++++----- test/algorithms/overlay/overlay_cases.hpp | 24 ++++++++++ .../set_operations/difference/difference.cpp | 8 +++- .../set_operations/union/test_union.hpp | 36 ++------------- .../algorithms/set_operations/union/union.cpp | 13 +++++- 5 files changed, 79 insertions(+), 46 deletions(-) diff --git a/test/algorithms/check_validity.hpp b/test/algorithms/check_validity.hpp index c02ff3f01..31e4f2df9 100644 --- a/test/algorithms/check_validity.hpp +++ b/test/algorithms/check_validity.hpp @@ -15,22 +15,38 @@ #include +template +inline bool input_is_valid(std::string const& case_id, std::string const& subcase, + Geometry const& geometry) +{ + std::string message; + bool const result = bg::is_valid(geometry, message); + if (! result) + { + std::cout << "WARNING: " << case_id << " Input [" << subcase + << "] is not considered as valid (" + << message << ") this can cause that output is invalid: " + << case_id << std::endl; + } + return result; +} + + template inline bool is_output_valid(Geometry const& geometry, std::string const& case_id, G1 const& g1, G2 const& g2, + bool ignore_validity_on_invalid_input, std::string& message) { - bool const result = bg::is_valid(geometry, message); - if (! result) + bool result = bg::is_valid(geometry, message); + if (! result && ignore_validity_on_invalid_input) { - // Check if input was valid. If not, do not report output validity - if (! bg::is_valid(g1) || ! bg::is_valid(g2)) + if (! input_is_valid(case_id, "a", g1) + || ! input_is_valid(case_id, "b", g2)) { - std::cout << "WARNING: Input is not considered as valid; " - << "this can cause that output is invalid: " << case_id - << std::endl; - return true; + // Because input is invalid, output validity is ignored + result = true; } } return result; @@ -48,9 +64,11 @@ struct check_validity bool apply(Geometry const& geometry, std::string const& case_id, G1 const& g1, G2 const& g2, - std::string& message) + std::string& message, + bool ignore_validity_on_invalid_input = true) { - return is_output_valid(geometry, case_id, g1, g2, message); + return is_output_valid(geometry, case_id, g1, g2, + ignore_validity_on_invalid_input, message); } }; @@ -63,12 +81,14 @@ struct check_validity bool apply(Geometry const& geometry, std::string const& case_id, G1 const& g1, G2 const& g2, - std::string& message) + std::string& message, + bool ignore_validity_on_invalid_input = true) { typedef typename boost::range_value::type single_type; for (single_type const& element : geometry) { - if (! is_output_valid(element, case_id, g1, g2, message)) + if (! is_output_valid(element, case_id, g1, g2, + ignore_validity_on_invalid_input, message)) { return false; } diff --git a/test/algorithms/overlay/overlay_cases.hpp b/test/algorithms/overlay/overlay_cases.hpp index a1aa5e475..225275240 100644 --- a/test/algorithms/overlay/overlay_cases.hpp +++ b/test/algorithms/overlay/overlay_cases.hpp @@ -1041,6 +1041,12 @@ static std::string issue_566_b[2] = "POLYGON((0 0,0.148086 -7.06952,10.1459 -6.86009,9.99781 0.209424,0 0))" }; +static std::string issue_690[2] = +{ + "POLYGON((667.934919263624237828481 -491.49318253425167313253,963.147330411699954311189 -168.898750642006632460834,972.814262587873145093909 -165.027657854956288474568,981.868038427448027505307 -170.171982894396819574467,983.490980059854678074771 -180.457944080522594276772,980.852669588300045688811 -185.101249357993367539166,290.852669588299988845392 -939.101249357993424382585,281.185737412126854906091 -942.972342145043739947141,272.131961572551972494693 -937.828017105603180425533,270.50901994014526508181 -927.542055919477434144937,273.147330411700011154608 -922.898750642006575617415,652.663832735933624462632 -508.180717667409339810547,658.329748792524242162472 -512.69913494618185723084,650.188373585171007107419 -506.206604869410682567832,650.188373585171007107419 -495.793395130589317432168,658.329748792524242162472 -489.30086505381814276916,667.934919263624237828481 -491.49318253425167313253))", + "POLYGON((925 686,920.481877622304750730109 676.618022210383628589625,910.329748792524242162472 674.30086505381814276916,902.188373585171007107419 680.793395130589260588749,902.188373585171007107419 691.206604869410739411251,910.329748792524242162472 697.69913494618185723084,920.481877622304750730109 695.381977789616371410375,925 686))" +}; + static std::string issue_838[2] = { "POLYGON((27162.5232832765 -40045.435290614478,27162.764636849268 -40045.321663646188,27164.74034168441 -40044.391828870466,27164.854765308635 -40044.634874609801,27164.613411735867 -40044.748501578091,27162.637706900725 -40045.678336353812,27162.5232832765 -40045.435290614478))", @@ -1053,6 +1059,24 @@ static std::string issue_861[2] = "POLYGON((0.999994299999858893279736093973 0.000000000000000000000000000000 , 0.239056281157559169514570385218 0.000000000000000000000000000000 , 0.073239184141848157061360780062 0.213576637616646664019626200570 , 0.999994299999858893279736093973 0.000000000000000000000000000000))" }; +static std::string issue_875[2] = +{ + "POLYGON((-46.499997761818364 -23.318506263117456,-46.499999998470159 26.305250946791375,-5.3405104310993323 15.276598956337693,37.500000001521741 -9.4573812741570009,37.500000001521741 -29.970448623772313,-38.166710648232517 -29.970440761860232,-46.094160894726727 -23.318520183850637,-46.499997761818364 -23.318506263117456))", + "POLYGON((-67.554314795325794 -23.318900735763236,-62.596713294359084 -17.33359695046795,-60.775620215083222 -15.852879652420938,-58.530163386780792 -15.186307709861694,-56.202193256444019 -15.435360658555282,-54.146122173314907 -16.562122444733632,-46.093707539928616 -23.318900593694593,-67.554314795325794 -23.318900735763236))" +}; + +static std::string issue_876a[2] = +{ + "POLYGON((-12.348592836283077 -24.307738740001128,-41.849629816470362 0.44657841289972566,-43.93192354390343 1.5953436102420255,-46.29667314132071 1.8752581961977057,-46.50000184857911 1.8191141367510681,-46.499999998470003 33.093636483932755,37.500000001521677 33.093636483932414,37.500000001521677 -33.09363648327178,-1.8779562757967945 -33.093638112618237,-12.348592836283077 -24.307738740001128))", + "POLYGON((-24.958697324691109 -13.726596811192508,-23.487544907371284 -15.559526963320764,-22.825279893545986 -17.819579221226945,-23.07272612812282 -20.162681116069621,-24.165778212709604 -22.183251915571645,-89.244978527106397 -22.179296124972666,-78.129783911175977 -8.7599622312850443,-30.874278746584466 -8.7628346218826891,-24.958697324691109 -13.726596811192508))" +}; + +static std::string issue_876b[2] = +{ + "POLYGON((-24.0482387183879496 -37.4313973992433375,-33.3495047556582449 -29.626708497888103,-36.5200226063477373 -27.5648148400831587,-39.4272653484940747 -26.8296944564690421,-41.9200722819054548 -27.2887150170597579,-43.732554394428881 -28.7766577741327865,-46.4999999984738537 -32.7358335543285648,-46.4999999984700025 37.4313974000880307,37.5000000015215846 37.4313974000876897,37.5000000015215846 -37.4313973992433375,-24.0482387183879496 -37.4313973992433375))", + "POLYGON((-71.6230763305201634 -132.587678014412745,-106.959839171856814 -102.936613347248112,-40.4477408440520776 -23.6705812141075285,-5.11097800271543878 -53.3216458812721612,-71.6230763305201634 -132.587678014412745))" +}; + static std::string ggl_list_20120229_volker[3] = { "POLYGON((1716 1554,2076 2250,2436 2352,2796 1248,3156 2484,3516 2688,3516 2688,3156 2484,2796 1248,2436 2352,2076 2250, 1716 1554))", diff --git a/test/algorithms/set_operations/difference/difference.cpp b/test/algorithms/set_operations/difference/difference.cpp index b77d82c0a..403c79e83 100644 --- a/test/algorithms/set_operations/difference/difference.cpp +++ b/test/algorithms/set_operations/difference/difference.cpp @@ -570,6 +570,12 @@ void test_all() settings); } + TEST_DIFFERENCE(issue_875, 1, 3468.77515, 1, 105.425816, 2); +#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) + TEST_DIFFERENCE(issue_876a, 1, 4728.89916, 1, 786.29563, 2); +#endif + TEST_DIFFERENCE(issue_876b, 1, 6114.18234, 1, 4754.29449, count_set(1, 2)); + TEST_DIFFERENCE(mysql_21977775, 2, 160.856568913, 2, 92.3565689126, 4); TEST_DIFFERENCE(mysql_21965285, 1, 92.0, 1, 14.0, 1); TEST_DIFFERENCE(mysql_23023665_1, 1, 92.0, 1, 142.5, 2); @@ -627,7 +633,7 @@ int test_main(int, char* []) // Not yet fully tested for float and long double. // The difference algorithm can generate (additional) slivers // Many of the failures are self-intersection points. - BoostGeometryWriteExpectedFailures(12, 10, 17, 12); + BoostGeometryWriteExpectedFailures(19, 10, 17, 12); #endif return 0; diff --git a/test/algorithms/set_operations/union/test_union.hpp b/test/algorithms/set_operations/union/test_union.hpp index 55c468134..3ea139d59 100644 --- a/test/algorithms/set_operations/union/test_union.hpp +++ b/test/algorithms/set_operations/union/test_union.hpp @@ -51,30 +51,10 @@ struct ut_settings : public ut_base_settings { - ut_settings() - : percentage(0.001) - {} - - double percentage; + double percentage = 0.001; + bool ignore_validity_on_invalid_input = true; }; -#if defined(BOOST_GEOMETRY_TEST_CHECK_VALID_INPUT) -template -inline void check_input_validity(std::string const& caseid, int case_index, - Geometry const& geometry) -{ - std::string message; - if (!bg::is_valid(geometry, message)) - { - std::cout << caseid << " Input [" - << case_index << "] not valid" << std::endl - << " (" << message << ")" << std::endl; - } -} -#endif - - - template inline std::size_t num_points(Range const& rng, bool add_for_open = false) { @@ -100,15 +80,6 @@ void test_union(std::string const& caseid, G1 const& g1, G2 const& g2, typedef typename setop_output_type::type result_type; result_type clip; -#if defined(BOOST_GEOMETRY_DEBUG_ROBUSTNESS) - std::cout << "*** UNION " << caseid << std::endl; -#endif - -#if defined(BOOST_GEOMETRY_TEST_CHECK_VALID_INPUT) - check_input_validity(caseid, 0, g1); - check_input_validity(caseid, 1, g2); -#endif - // Check normal behaviour bg::union_(g1, g2, clip); @@ -128,7 +99,8 @@ void test_union(std::string const& caseid, G1 const& g1, G2 const& g2, if (settings.test_validity()) { std::string message; - bool const valid = check_validity::apply(clip, caseid, g1, g2, message); + bool const valid = check_validity::apply(clip, caseid, + g1, g2, message, settings.ignore_validity_on_invalid_input); BOOST_CHECK_MESSAGE(valid, "union: " << caseid << " not valid: " << message << " type: " << (type_for_assert_message())); diff --git a/test/algorithms/set_operations/union/union.cpp b/test/algorithms/set_operations/union/union.cpp index 7daec1990..005e13e7e 100644 --- a/test/algorithms/set_operations/union/union.cpp +++ b/test/algorithms/set_operations/union/union.cpp @@ -430,6 +430,17 @@ void test_areal() TEST_UNION_REV(issue_566_a, 1, 0, -1, 214.3728); TEST_UNION_REV(issue_566_b, 1, 0, -1, 214.3728); +#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) + { + // With rescaling, the input (was already an output of a previous step) + // is somehow considered as invalid. Output is also invalid. + // Without rescaling, the same input is considered as valid + ut_settings settings; + settings.ignore_validity_on_invalid_input = false; + TEST_UNION_WITH(issue_690, 2, 0, -1, 25492.0505); + } +#endif + TEST_UNION(issue_838, 1, 0, -1, expectation_limits(1.3333, 1.33785)); TEST_UNION_REV(issue_838, 1, 0, -1, expectation_limits(1.3333, 1.33785)); @@ -597,7 +608,7 @@ int test_main(int, char* []) #endif #if defined(BOOST_GEOMETRY_TEST_FAILURES) - BoostGeometryWriteExpectedFailures(3, 1, 2, 0); + BoostGeometryWriteExpectedFailures(4, 1, 2, 0); #endif return 0; From f3fd231ff0be63696f7839c6974a37c21341200a Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 4 Aug 2021 15:17:21 +0200 Subject: [PATCH 31/74] [test] Remove BOOST_NO_AUTO_PTR definition from Jamfile to avoid redefinition warnings. --- test/Jamfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/Jamfile b/test/Jamfile index 023b53f06..492e41aa3 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -4,8 +4,8 @@ # Copyright (c) 2008-2012 Bruno Lalande, Paris, France. # Copyright (c) 2009-2018 Mateusz Loskot, London, UK. # -# This file was modified by Oracle on 2017, 2018, 2019. -# Modifications copyright (c) 2017-2019 Oracle and/or its affiliates. +# This file was modified by Oracle on 2017-2021. +# Modifications copyright (c) 2017-2021 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, @@ -24,7 +24,6 @@ project boost-geometry-test clang:-Wno-unneeded-internal-declaration # supress warning by Boost.None intel:BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE windows,intel:/bigobj - BOOST_NO_AUTO_PTR # disable the deprecated std::auto_ptr support in SmartPtr and Core ; # Run minimal testset From 68274399ce4c318b326a3deef181e8073817b37f Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 5 Aug 2021 00:15:10 +0200 Subject: [PATCH 32/74] [algorithms][io] Add workaround for gcc-5 name lookup. --- include/boost/geometry/algorithms/detail/visit.hpp | 5 +++-- include/boost/geometry/io/wkt/write.hpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/visit.hpp b/include/boost/geometry/algorithms/detail/visit.hpp index 60958f4b4..bbc2f4e86 100644 --- a/include/boost/geometry/algorithms/detail/visit.hpp +++ b/include/boost/geometry/algorithms/detail/visit.hpp @@ -217,7 +217,8 @@ struct visit_breadth_first bool result = true; traits::iter_visit>::apply([&](auto && g) { - result = visit_or_enqueue(function, std::forward(g), queue, it); + result = visit_breadth_first::visit_or_enqueue( + function, std::forward(g), queue, it); }, it); if (! result) @@ -235,7 +236,7 @@ struct visit_breadth_first // so this call can be avoided. traits::iter_visit>::apply([&](auto && g) { - set_iterators(std::forward(g), it, end); + visit_breadth_first::set_iterators(std::forward(g), it, end); }, queue.front()); queue.pop_front(); } diff --git a/include/boost/geometry/io/wkt/write.hpp b/include/boost/geometry/io/wkt/write.hpp index aa52d072f..73b374c9e 100644 --- a/include/boost/geometry/io/wkt/write.hpp +++ b/include/boost/geometry/io/wkt/write.hpp @@ -478,9 +478,10 @@ struct wkt static inline void apply(OutputStream& os, Geometry const& geometry, bool force_closure) { - output_or_recursive_call(os, geometry, force_closure); + wkt::output_or_recursive_call(os, geometry, force_closure); } +private: template < typename OutputStream, typename Geom, @@ -501,7 +502,7 @@ struct wkt traits::iter_visit::apply([&](auto const& g) { - output_or_recursive_call(os, g, force_closure); + wkt::output_or_recursive_call(os, g, force_closure); }, it); } From 5110ec7daea0fef72ebdbd41c7f3392502c55945 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 13 Aug 2021 00:54:38 +0200 Subject: [PATCH 33/74] Add missing headers to satisfy Boost header policy. --- include/boost/geometry/algorithms/azimuth.hpp | 2 + .../index/detail/algorithms/bounds.hpp | 9 +++- .../comparable_distance_centroid.hpp | 7 +++ .../algorithms/comparable_distance_far.hpp | 7 +++ .../algorithms/comparable_distance_near.hpp | 7 +++ .../index/detail/algorithms/content.hpp | 9 +++- .../algorithms/intersection_content.hpp | 7 ++- .../index/detail/algorithms/is_valid.hpp | 5 ++- .../index/detail/algorithms/margin.hpp | 9 +++- .../detail/algorithms/path_intersection.hpp | 5 ++- .../algorithms/segment_intersection.hpp | 9 +++- .../index/detail/distance_predicates.hpp | 6 +-- .../geometry/index/detail/predicates.hpp | 21 +++++---- .../geometry/index/detail/rtree/adaptors.hpp | 8 +++- .../geometry/index/detail/rtree/iterators.hpp | 8 ++++ .../index/detail/rtree/kmeans/kmeans.hpp | 6 ++- .../index/detail/rtree/kmeans/split.hpp | 45 +++++++++++++------ .../index/detail/rtree/node/node_elements.hpp | 5 +++ .../detail/rtree/node/scoped_deallocator.hpp | 6 +++ .../detail/rtree/node/variant_dynamic.hpp | 13 +++++- .../detail/rtree/node/variant_static.hpp | 7 +++ .../index/detail/rtree/node/weak_dynamic.hpp | 35 ++++++++++++++- .../index/detail/rtree/node/weak_static.hpp | 7 +++ .../index/detail/rtree/node/weak_visitor.hpp | 6 +++ .../index/detail/rtree/pack_create.hpp | 11 +++-- .../index/detail/rtree/query_iterators.hpp | 8 +++- .../detail/rtree/rstar/choose_next_node.hpp | 6 ++- .../index/detail/rtree/rstar/insert.hpp | 5 +++ .../index/detail/rtree/utilities/gl_draw.hpp | 13 +++++- .../index/detail/rtree/utilities/print.hpp | 8 +++- .../detail/rtree/visitors/distance_query.hpp | 6 +++ .../index/detail/rtree/visitors/insert.hpp | 10 +++-- .../index/detail/rtree/visitors/iterator.hpp | 7 +++ .../index/detail/rtree/visitors/remove.hpp | 10 +++-- .../detail/rtree/visitors/spatial_query.hpp | 4 ++ .../geometry/index/detail/serialization.hpp | 22 ++++++++- .../geometry/index/detail/translator.hpp | 6 ++- include/boost/geometry/index/parameters.hpp | 6 +-- .../strategies/distance/comparable.hpp | 2 + .../geometry/strategies/distance/services.hpp | 2 + .../geographic/buffer_point_circle.hpp | 10 ++--- .../strategies/intersection_result.hpp | 6 +-- .../geometry/strategies/relate/geographic.hpp | 1 + .../strategies/simplify/spherical.hpp | 1 + 44 files changed, 314 insertions(+), 79 deletions(-) diff --git a/include/boost/geometry/algorithms/azimuth.hpp b/include/boost/geometry/algorithms/azimuth.hpp index 28e5491e7..26c9a5530 100644 --- a/include/boost/geometry/algorithms/azimuth.hpp +++ b/include/boost/geometry/algorithms/azimuth.hpp @@ -23,6 +23,8 @@ #include #include +#include + #include #include #include diff --git a/include/boost/geometry/index/detail/algorithms/bounds.hpp b/include/boost/geometry/index/detail/algorithms/bounds.hpp index 1828a2467..999246d9c 100644 --- a/include/boost/geometry/index/detail/algorithms/bounds.hpp +++ b/include/boost/geometry/index/detail/algorithms/bounds.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019-2020. -// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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, @@ -15,6 +15,11 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP +#include +#include +#include +#include + #include namespace boost { namespace geometry { namespace index { namespace detail diff --git a/include/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp b/include/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp index c4e44cae1..6afe03eec 100644 --- a/include/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp +++ b/include/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +15,9 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_CENTROID_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_CENTROID_HPP +#include +#include + #include #include diff --git a/include/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp b/include/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp index 214fbf6aa..102ac545e 100644 --- a/include/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp +++ b/include/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +15,9 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_FAR_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_FAR_HPP +#include +#include + #include #include diff --git a/include/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp b/include/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp index 15368a7d2..4f2905f3a 100644 --- a/include/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp +++ b/include/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +15,9 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_NEAR_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_NEAR_HPP +#include +#include + #include namespace boost { namespace geometry { namespace index { namespace detail { diff --git a/include/boost/geometry/index/detail/algorithms/content.hpp b/include/boost/geometry/index/detail/algorithms/content.hpp index 7833ae377..d698a3208 100644 --- a/include/boost/geometry/index/detail/algorithms/content.hpp +++ b/include/boost/geometry/index/detail/algorithms/content.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 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, @@ -15,7 +15,12 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP +#include +#include #include +#include +#include +#include namespace boost { namespace geometry { namespace index { namespace detail { diff --git a/include/boost/geometry/index/detail/algorithms/intersection_content.hpp b/include/boost/geometry/index/detail/algorithms/intersection_content.hpp index 880540bc0..1a2cd28bc 100644 --- a/include/boost/geometry/index/detail/algorithms/intersection_content.hpp +++ b/include/boost/geometry/index/detail/algorithms/intersection_content.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019-2020. -// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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,6 +20,9 @@ #include +#include +#include + namespace boost { namespace geometry { namespace index { namespace detail { // Util to distinguish between default and non-default index strategy diff --git a/include/boost/geometry/index/detail/algorithms/is_valid.hpp b/include/boost/geometry/index/detail/algorithms/is_valid.hpp index 0d57ed57e..5cd241c29 100644 --- a/include/boost/geometry/index/detail/algorithms/is_valid.hpp +++ b/include/boost/geometry/index/detail/algorithms/is_valid.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 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,6 +18,7 @@ #include #include +#include #include namespace boost { namespace geometry { namespace index { namespace detail { diff --git a/include/boost/geometry/index/detail/algorithms/margin.hpp b/include/boost/geometry/index/detail/algorithms/margin.hpp index 2033f4a53..5a05d3c02 100644 --- a/include/boost/geometry/index/detail/algorithms/margin.hpp +++ b/include/boost/geometry/index/detail/algorithms/margin.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 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, @@ -15,7 +15,12 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP +#include +#include #include +#include +#include +#include // WARNING! comparable_margin() will work only if the same Geometries are compared // so it shouldn't be used in the case of Variants! diff --git a/include/boost/geometry/index/detail/algorithms/path_intersection.hpp b/include/boost/geometry/index/detail/algorithms/path_intersection.hpp index 4803f5914..ab0860349 100644 --- a/include/boost/geometry/index/detail/algorithms/path_intersection.hpp +++ b/include/boost/geometry/index/detail/algorithms/path_intersection.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 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,6 +20,7 @@ #include +#include #include diff --git a/include/boost/geometry/index/detail/algorithms/segment_intersection.hpp b/include/boost/geometry/index/detail/algorithms/segment_intersection.hpp index a2717d26e..674d9f5f8 100644 --- a/include/boost/geometry/index/detail/algorithms/segment_intersection.hpp +++ b/include/boost/geometry/index/detail/algorithms/segment_intersection.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020, Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021, 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, @@ -15,9 +15,14 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SEGMENT_INTERSECTION_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SEGMENT_INTERSECTION_HPP +#include #include +#include +#include #include +#include +#include namespace boost { namespace geometry { namespace index { namespace detail { diff --git a/include/boost/geometry/index/detail/distance_predicates.hpp b/include/boost/geometry/index/detail/distance_predicates.hpp index dcd8d1243..69ce45633 100644 --- a/include/boost/geometry/index/detail/distance_predicates.hpp +++ b/include/boost/geometry/index/detail/distance_predicates.hpp @@ -5,8 +5,8 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019-2020. -// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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 +22,7 @@ #include #include #include - +#include #include namespace boost { namespace geometry { namespace index { namespace detail { diff --git a/include/boost/geometry/index/detail/predicates.hpp b/include/boost/geometry/index/detail/predicates.hpp index 0ae8defe8..c1a8b73c4 100644 --- a/include/boost/geometry/index/detail/predicates.hpp +++ b/include/boost/geometry/index/detail/predicates.hpp @@ -20,9 +20,13 @@ //#include #include +#include +#include #include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace predicates { @@ -31,10 +35,10 @@ namespace predicates { // predicates // ------------------------------------------------------------------ // -template +template ::value> struct satisfies_impl { - satisfies_impl() : fun(NULL) {} + satisfies_impl() : fun(nullptr) {} satisfies_impl(Fun f) : fun(f) {} Fun * fun; }; @@ -42,20 +46,19 @@ struct satisfies_impl template struct satisfies_impl { - satisfies_impl() {} + satisfies_impl() = default; satisfies_impl(Fun const& f) : fun(f) {} Fun fun; }; template -struct satisfies - : satisfies_impl::value> +struct satisfies : satisfies_impl { - typedef satisfies_impl::value> base; + using base_t = satisfies_impl; - satisfies() {} - satisfies(Fun const& f) : base(f) {} - satisfies(base const& b) : base(b) {} + satisfies() = default; + satisfies(Fun const& f) : base_t(f) {} + satisfies(base_t const& b) : base_t(b) {} }; // ------------------------------------------------------------------ // diff --git a/include/boost/geometry/index/detail/rtree/adaptors.hpp b/include/boost/geometry/index/detail/rtree/adaptors.hpp index 4e0eb9ba0..4da3d7b94 100644 --- a/include/boost/geometry/index/detail/rtree/adaptors.hpp +++ b/include/boost/geometry/index/detail/rtree/adaptors.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,13 +15,13 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ADAPTORS_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ADAPTORS_HPP -#include -#include +#include #include namespace boost { namespace geometry { namespace index { +// Forward declaration template class rtree; diff --git a/include/boost/geometry/index/detail/rtree/iterators.hpp b/include/boost/geometry/index/detail/rtree/iterators.hpp index a47dd7ea4..1d5cd1a23 100644 --- a/include/boost/geometry/index/detail/rtree/iterators.hpp +++ b/include/boost/geometry/index/detail/rtree/iterators.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +15,10 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP +#include + +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators { template diff --git a/include/boost/geometry/index/detail/rtree/kmeans/kmeans.hpp b/include/boost/geometry/index/detail/rtree/kmeans/kmeans.hpp index 3f61482b2..34edcfa7c 100644 --- a/include/boost/geometry/index/detail/rtree/kmeans/kmeans.hpp +++ b/include/boost/geometry/index/detail/rtree/kmeans/kmeans.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +15,6 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_KMEANS_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_KMEANS_HPP -#include +#include #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_KMEANS_HPP diff --git a/include/boost/geometry/index/detail/rtree/kmeans/split.hpp b/include/boost/geometry/index/detail/rtree/kmeans/split.hpp index f19654972..aa9dfbba4 100644 --- a/include/boost/geometry/index/detail/rtree/kmeans/split.hpp +++ b/include/boost/geometry/index/detail/rtree/kmeans/split.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,13 +15,17 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_SPLIT_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_SPLIT_HPP -#include -#include +#include +#include namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { +// TODO: This should be defined in options.hpp +// For now it's defined here to satisfy Boost header policy +struct split_kmeans_tag {}; + namespace kmeans { // some details @@ -56,25 +64,34 @@ namespace kmeans { // 4. Pamietac o parametryzacji kontenera z nadmiarowymi elementami // PS. Z R* reinsertami moze byc masakra -template -class split +template +class split { protected: - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::box_type box_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; + typedef typename MembersHolder::size_type size_type; - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; public: + typedef index::detail::varray + < + typename rtree::elements_type::type::value_type, + 1 + > nodes_container_type; + template - static inline void apply(node* & root_node, - size_t & leafs_level, + static inline void apply(nodes_container_type & additional_nodes, Node & n, - internal_node *parent_node, - size_t current_child_index, - Translator const& tr, - Allocators & allocators) + box_type & n_box, + parameters_type const& parameters, + translator_type const& translator, + allocators_type & allocators) { } diff --git a/include/boost/geometry/index/detail/rtree/node/node_elements.hpp b/include/boost/geometry/index/detail/rtree/node/node_elements.hpp index 0e5848987..ca034a8d7 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node_elements.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -15,6 +19,7 @@ #include #include #include +#include namespace boost { namespace geometry { namespace index { diff --git a/include/boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp b/include/boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp index 0062402d4..a63aad884 100644 --- a/include/boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp +++ b/include/boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +15,8 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { diff --git a/include/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp b/include/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp index 52b253ccf..95c709616 100644 --- a/include/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp +++ b/include/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,7 +15,14 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP -#include +#include +#include +#include +#include + +#include +#include +#include namespace boost { namespace geometry { namespace index { diff --git a/include/boost/geometry/index/detail/rtree/node/variant_static.hpp b/include/boost/geometry/index/detail/rtree/node/variant_static.hpp index c30998d68..624ce472e 100644 --- a/include/boost/geometry/index/detail/rtree/node/variant_static.hpp +++ b/include/boost/geometry/index/detail/rtree/node/variant_static.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +15,9 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP +#include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { diff --git a/include/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp b/include/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp index eadda62a9..1e96ed918 100644 --- a/include/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp +++ b/include/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,10 +15,23 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP +#include +#include + +#include +#include +#include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { +// TODO: This should be defined in options.hpp +// For now it's defined here to satisfy Boost header policy +struct node_weak_dynamic_tag {}; +struct node_weak_static_tag {}; + template struct weak_internal_node : public weak_node @@ -87,7 +104,7 @@ struct visitor struct internal_node_alloc { - typedef typename internal_nod + typedef typename internal_node < Value, Parameters, Box, allocators, @@ -116,6 +133,22 @@ struct leaf_alloc >::template rebind_alloc type; }; +template +struct node_alloc +{ + typedef typename weak_node + < + Value, Parameters, Box, + allocators, + Tag + >::type node_type; + + typedef typename ::boost::container::allocator_traits + < + Allocator + >::template rebind_alloc type; +}; + template class allocators : public internal_node_alloc::type diff --git a/include/boost/geometry/index/detail/rtree/node/weak_static.hpp b/include/boost/geometry/index/detail/rtree/node/weak_static.hpp index ac9e69cec..65b80266d 100644 --- a/include/boost/geometry/index/detail/rtree/node/weak_static.hpp +++ b/include/boost/geometry/index/detail/rtree/node/weak_static.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +15,9 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP +#include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { diff --git a/include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp b/include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp index 08d84778e..a6beaf090 100644 --- a/include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp +++ b/include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +15,8 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { diff --git a/include/boost/geometry/index/detail/rtree/pack_create.hpp b/include/boost/geometry/index/detail/rtree/pack_create.hpp index 4cfd39669..6a8ffe6aa 100644 --- a/include/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/include/boost/geometry/index/detail/rtree/pack_create.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2020 Caian Benedicto, Campinas, Brazil. // -// This file was modified by Oracle on 2019. -// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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,12 +18,15 @@ #include +#include #include + +#include #include #include +#include #include - -#include +#include namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { diff --git a/include/boost/geometry/index/detail/rtree/query_iterators.hpp b/include/boost/geometry/index/detail/rtree/query_iterators.hpp index 8822bcf04..3ca0bafdf 100644 --- a/include/boost/geometry/index/detail/rtree/query_iterators.hpp +++ b/include/boost/geometry/index/detail/rtree/query_iterators.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019. -// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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, @@ -17,6 +17,10 @@ #include +#include +#include +#include + //#define BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators { diff --git a/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp b/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp index 7ba5f0f99..4ea9060f8 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019. -// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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,6 +27,8 @@ #include #include +#include +#include #include namespace boost { namespace geometry { namespace index { diff --git a/include/boost/geometry/index/detail/rtree/rstar/insert.hpp b/include/boost/geometry/index/detail/rtree/rstar/insert.hpp index 8517b7f1b..ce830007a 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/insert.hpp @@ -19,7 +19,12 @@ #include +#include + #include +#include +#include +#include namespace boost { namespace geometry { namespace index { diff --git a/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp b/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp index bdabebf22..44933dac4 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019-2020. -// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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, @@ -15,7 +15,16 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP +#include + +#include +#include +#include #include +#include +#include + +#include namespace boost { namespace geometry { namespace index { namespace detail { diff --git a/include/boost/geometry/index/detail/rtree/utilities/print.hpp b/include/boost/geometry/index/detail/rtree/utilities/print.hpp index 2ed71a6b8..15d618eb6 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/print.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/print.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019-2020. -// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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, @@ -17,7 +17,11 @@ #include +#include +#include #include +#include +#include namespace boost { namespace geometry { namespace index { namespace detail { diff --git a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp index a40dbfe84..ede7b346e 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp @@ -15,6 +15,12 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_DISTANCE_QUERY_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_DISTANCE_QUERY_HPP +#include +#include +#include +#include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { diff --git a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp index 8b32c8176..5d158bc7d 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019-2020. -// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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, @@ -21,12 +21,14 @@ #include #include -#include #include #include - +#include #include +#include + +#include namespace boost { namespace geometry { namespace index { diff --git a/include/boost/geometry/index/detail/rtree/visitors/iterator.hpp b/include/boost/geometry/index/detail/rtree/visitors/iterator.hpp index 621231ae9..71127dcbe 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/iterator.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/iterator.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +15,9 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP +#include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { diff --git a/include/boost/geometry/index/detail/rtree/visitors/remove.hpp b/include/boost/geometry/index/detail/rtree/visitors/remove.hpp index 59f486163..7cdbb0344 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/remove.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/remove.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019. -// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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, @@ -15,11 +15,13 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_REMOVE_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_REMOVE_HPP +#include + +#include +#include #include #include -#include - namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { diff --git a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp index f0d30162c..5f2c07ea2 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp @@ -15,6 +15,10 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP +#include +#include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { diff --git a/include/boost/geometry/index/detail/serialization.hpp b/include/boost/geometry/index/detail/serialization.hpp index 71902d19f..909c38e3c 100644 --- a/include/boost/geometry/index/detail/serialization.hpp +++ b/include/boost/geometry/index/detail/serialization.hpp @@ -2,6 +2,10 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -9,11 +13,21 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP +#include +#include + //#include #include #include //#include +#include +#include + +#include +#include +#include + // TODO // how about using the unsigned type capable of storing Max in compile-time versions? @@ -26,7 +40,13 @@ // each geometry save without this info // TODO - move to index/detail/serialization.hpp -namespace boost { namespace geometry { namespace index { namespace detail { +namespace boost { namespace geometry { namespace index { + +// Forward declaration +template +class rtree; + +namespace detail { // TODO - use boost::move? template diff --git a/include/boost/geometry/index/detail/translator.hpp b/include/boost/geometry/index/detail/translator.hpp index 34960d226..900be6e73 100644 --- a/include/boost/geometry/index/detail/translator.hpp +++ b/include/boost/geometry/index/detail/translator.hpp @@ -2,8 +2,8 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019-2020. -// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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, @@ -15,6 +15,8 @@ #include +#include + namespace boost { namespace geometry { namespace index { namespace detail { diff --git a/include/boost/geometry/index/parameters.hpp b/include/boost/geometry/index/parameters.hpp index fdaef9284..477518866 100644 --- a/include/boost/geometry/index/parameters.hpp +++ b/include/boost/geometry/index/parameters.hpp @@ -4,8 +4,8 @@ // // Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2019-2020. -// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2019-2021. +// Modifications copyright (c) 2019-2021 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, @@ -15,13 +15,13 @@ #ifndef BOOST_GEOMETRY_INDEX_PARAMETERS_HPP #define BOOST_GEOMETRY_INDEX_PARAMETERS_HPP - #include #include #include +#include namespace boost { namespace geometry { namespace index { diff --git a/include/boost/geometry/strategies/distance/comparable.hpp b/include/boost/geometry/strategies/distance/comparable.hpp index 34a828cfe..3a6d8300b 100644 --- a/include/boost/geometry/strategies/distance/comparable.hpp +++ b/include/boost/geometry/strategies/distance/comparable.hpp @@ -14,6 +14,8 @@ #include #include +#include + namespace boost { namespace geometry { diff --git a/include/boost/geometry/strategies/distance/services.hpp b/include/boost/geometry/strategies/distance/services.hpp index 4ac35c6dd..5ce3cd98b 100644 --- a/include/boost/geometry/strategies/distance/services.hpp +++ b/include/boost/geometry/strategies/distance/services.hpp @@ -14,6 +14,8 @@ #include #include +#include + namespace boost { namespace geometry { diff --git a/include/boost/geometry/strategies/geographic/buffer_point_circle.hpp b/include/boost/geometry/strategies/geographic/buffer_point_circle.hpp index 8d6643d73..d9efba917 100644 --- a/include/boost/geometry/strategies/geographic/buffer_point_circle.hpp +++ b/include/boost/geometry/strategies/geographic/buffer_point_circle.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2018-2019 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 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, @@ -17,12 +17,12 @@ #include +#include +#include +#include #include #include -#include - - namespace boost { namespace geometry { diff --git a/include/boost/geometry/strategies/intersection_result.hpp b/include/boost/geometry/strategies/intersection_result.hpp index 4b5aa1c46..94aae51d8 100644 --- a/include/boost/geometry/strategies/intersection_result.hpp +++ b/include/boost/geometry/strategies/intersection_result.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015, 2016. -// Modifications copyright (c) 2015-2016 Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2021. +// Modifications copyright (c) 2015-2021 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, @@ -15,9 +15,9 @@ #include +#include #include - namespace boost { namespace geometry { diff --git a/include/boost/geometry/strategies/relate/geographic.hpp b/include/boost/geometry/strategies/relate/geographic.hpp index 60c6b9e58..4f556e953 100644 --- a/include/boost/geometry/strategies/relate/geographic.hpp +++ b/include/boost/geometry/strategies/relate/geographic.hpp @@ -13,6 +13,7 @@ // TEMP - move to strategy #include +#include #include #include #include diff --git a/include/boost/geometry/strategies/simplify/spherical.hpp b/include/boost/geometry/strategies/simplify/spherical.hpp index 0858087f3..4ff51b38c 100644 --- a/include/boost/geometry/strategies/simplify/spherical.hpp +++ b/include/boost/geometry/strategies/simplify/spherical.hpp @@ -12,6 +12,7 @@ #include +#include #include #include From 4bdfe1bf05b92d881e5ab3502ea82c179532ea61 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 13 Aug 2021 17:44:13 +0200 Subject: [PATCH 34/74] [test] Fix warnings. --- test/algorithms/line_interpolate.cpp | 43 ++++++++++++------------ test/geometries/boost_array_as_point.cpp | 32 ++++++++---------- test/strategies/envelope_segment.cpp | 7 ++-- test/util/algorithm.cpp | 18 +++++----- 4 files changed, 48 insertions(+), 52 deletions(-) diff --git a/test/algorithms/line_interpolate.cpp b/test/algorithms/line_interpolate.cpp index c3338c693..2b5c717e2 100644 --- a/test/algorithms/line_interpolate.cpp +++ b/test/algorithms/line_interpolate.cpp @@ -4,6 +4,7 @@ // Copyright (c) 2018, 2021, 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 // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -204,13 +205,13 @@ void test_car() test(l1, 0, "MULTIPOINT((1 1))"); // The following type of test is not robust; // (1 3) could be missing due to floating point round off errors - //test(l1, 0.1, "MULTIPOINT((1.4 1)(1.8 1)(2 1.2)(2 1.6)(2 2)(1.6 2)\ - // (1.2 2)(1 2.2)(1 2.6)(1 3))"); + //test(l1, 0.1, "MULTIPOINT((1.4 1)(1.8 1)(2 1.2)(2 1.6)(2 2)(1.6 2)" + // "(1.2 2)(1 2.2)(1 2.6)(1 3))"); // Tests are more robust if you directly pass the distance - test_distance(l1, 0.4, "MULTIPOINT((1.4 1)(1.8 1)(2 1.2)(2 1.6)(2 2)(1.6 2)\ - (1.2 2)(1 2.2)(1 2.6)(1 3))"); - test(l1, 0.09, "MULTIPOINT((1.36 1)(1.72 1)(2 1.08)(2 1.44)(2 1.8)\ - (1.84 2)(1.48 2)(1.12 2)(1 2.24)(1 2.6)(1 2.96))"); + test_distance(l1, 0.4, "MULTIPOINT((1.4 1)(1.8 1)(2 1.2)(2 1.6)(2 2)(1.6 2)" + "(1.2 2)(1 2.2)(1 2.6)(1 3))"); + test(l1, 0.09, "MULTIPOINT((1.36 1)(1.72 1)(2 1.08)(2 1.44)(2 1.8)" + "(1.84 2)(1.48 2)(1.12 2)(1 2.24)(1 2.6)(1 2.96))"); test(l1, 0.21, "MULTIPOINT((1.84 1)(2 1.68)(1.48 2)(1 2.36))"); test(l1, 0.4, "MULTIPOINT((2 1.6)(1 2.2))"); test(l1, 0.6, "MULTIPOINT((1.6 2))"); @@ -241,18 +242,18 @@ void test_sph() test(l1, 1, "POINT(1 3)"); test(l1, 0, "MULTIPOINT((1 1))"); - test(l1, 0.09, "MULTIPOINT((1.35999 1.00004)(1.71997 1.00003)\ - (2 1.07995)(2 1.43988)(2 1.79981)(1.84016 2.00004)\ - (1.48001 2.00008)(1.11986 2.00003)(1 2.24014)\ - (1 2.60008)(1 2.96001))"); + test(l1, 0.09, "MULTIPOINT((1.35999 1.00004)(1.71997 1.00003)" + "(2 1.07995)(2 1.43988)(2 1.79981)(1.84016 2.00004)" + "(1.48001 2.00008)(1.11986 2.00003)(1 2.24014)" + "(1 2.60008)(1 2.96001))"); test(l1, 0.21, "MULTIPOINT((1.83997 1.00002)(2 1.67983)(1.48001 2.00008)(1 2.36012))"); test(l1, 0.4, "MULTIPOINT((2 1.5998477098527744)(1 2.2001522994279883))"); test(l1, 0.6, "MULTIPOINT((1.6000609543036084 2.0000730473928678))"); test(l1, 1, "MULTIPOINT((1 3))"); - test(l2, 0.3, "MULTIPOINT((5.3014893312120446 1.0006787676128222)\ - (11.600850053156366 1.0085030143490989)\ - (17.9002174825842 1.0041514208039872))"); + test(l2, 0.3, "MULTIPOINT((5.3014893312120446 1.0006787676128222)" + "(11.600850053156366 1.0085030143490989)" + "(17.9002174825842 1.0041514208039872))"); } template @@ -294,18 +295,18 @@ void test_geo(Strategy str) test(l1, 1, "POINT(1 3)", str); test(l1, 0, "MULTIPOINT((1 1))", str); - test(l1, 0.11, "MULTIPOINT((1.43851 1.00004)(1.87702 1.00002)(2 1.31761)\ - (2 1.75901)(1.80081 2.00005)(1.3621 2.00007)\ - (1 2.07708)(1 2.51847)(1 2.95986))", str); - test(l1, 0.21, "MULTIPOINT((1.83716 1.00002)(2 1.67875)(1.48176 2.00008)\ - (1 2.35796))", str); + test(l1, 0.11, "MULTIPOINT((1.43851 1.00004)(1.87702 1.00002)(2 1.31761)" + "(2 1.75901)(1.80081 2.00005)(1.3621 2.00007)" + "(1 2.07708)(1 2.51847)(1 2.95986))", str); + test(l1, 0.21, "MULTIPOINT((1.83716 1.00002)(2 1.67875)(1.48176 2.00008)" + "(1 2.35796))", str); test(l1, 0.4, "MULTIPOINT((2 1.598498298996567)(1 2.1974612279909937))", str); test(l1, 0.6, "MULTIPOINT((1.6013936980010324 2.0000734568388099))", str); test(l1, 1, "MULTIPOINT((1 3))", str); - test(l2, 0.3, "MULTIPOINT((5.306157814 1.0006937303)\ - (11.60351281 1.0085614548123072)\ - (17.90073492 1.004178475142552))", str); + test(l2, 0.3, "MULTIPOINT((5.306157814 1.0006937303)" + "(11.60351281 1.0085614548123072)" + "(17.90073492 1.004178475142552))", str); } template diff --git a/test/geometries/boost_array_as_point.cpp b/test/geometries/boost_array_as_point.cpp index 1cd49bf60..5a51357dc 100644 --- a/test/geometries/boost_array_as_point.cpp +++ b/test/geometries/boost_array_as_point.cpp @@ -4,27 +4,29 @@ // Copyright (c) 2010 Alfredo Correa // Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include + #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian) BOOST_GEOMETRY_REGISTER_BOOST_ARRAY_CS(cs::cartesian) BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian) - -#ifndef BOOST_NO_CXX11_HDR_ARRAY -#include BOOST_GEOMETRY_REGISTER_STD_ARRAY_CS(cs::cartesian) -#endif //BOOST_NO_CXX11_HDR_ARRAY int test_main(int, char* []) { @@ -32,18 +34,12 @@ int test_main(int, char* []) double p2[3] = {4,5,6}; boost::tuple p3(7,8,9); boost::array p4 = {{10,11,12}}; + std::array p5 = {{13,14,15}}; + std::clog << bg::distance(p1, p2) << std::endl; std::clog << bg::distance(p2, p3) << std::endl; std::clog << bg::distance(p3, p4) << std::endl; - -#ifndef BOOST_NO_CXX11_HDR_ARRAY -#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST - std::array p5 = {13,14,15}; -#else - std::array p5; p5[0] = 13; p5[1] = 14; p5[2] = 15; -#endif // BOOST_NO_CXX11_HDR_INITIALIZER_LIST std::clog << bg::distance(p4, p5) << std::endl; -#endif //BOOST_NO_CXX11_HDR_ARRAY return 0; } diff --git a/test/strategies/envelope_segment.cpp b/test/strategies/envelope_segment.cpp index 09610e3c0..77b66fbeb 100644 --- a/test/strategies/envelope_segment.cpp +++ b/test/strategies/envelope_segment.cpp @@ -1,7 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016-2018 Oracle and/or its affiliates. - +// Copyright (c) 2016-2021 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 @@ -12,8 +11,8 @@ #include #include #include -#include -#include +#include +#include template < diff --git a/test/util/algorithm.cpp b/test/util/algorithm.cpp index dd3f35430..e99a80e4c 100644 --- a/test/util/algorithm.cpp +++ b/test/util/algorithm.cpp @@ -22,14 +22,14 @@ void test_dimension(bg::util::index_constant<0>) { bool called = false; - bg::detail::for_each_index<0>([&](auto index) { called = true; }); + bg::detail::for_each_index<0>([&](auto) { called = true; }); BOOST_CHECK(!called); - BOOST_CHECK(bg::detail::all_indexes_of<0>([&](auto index) { return true; }) == true); - BOOST_CHECK(bg::detail::all_indexes_of<0>([&](auto index) { return false; }) == true); - BOOST_CHECK(bg::detail::any_index_of<0>([&](auto index) { return true; }) == false); - BOOST_CHECK(bg::detail::any_index_of<0>([&](auto index) { return false; }) == false); - BOOST_CHECK(bg::detail::none_index_of<0>([&](auto index) { return true; }) == true); - BOOST_CHECK(bg::detail::none_index_of<0>([&](auto index) { return false; }) == true); + BOOST_CHECK(bg::detail::all_indexes_of<0>([&](auto) { return true; }) == true); + BOOST_CHECK(bg::detail::all_indexes_of<0>([&](auto) { return false; }) == true); + BOOST_CHECK(bg::detail::any_index_of<0>([&](auto) { return true; }) == false); + BOOST_CHECK(bg::detail::any_index_of<0>([&](auto) { return false; }) == false); + BOOST_CHECK(bg::detail::none_index_of<0>([&](auto) { return true; }) == true); + BOOST_CHECK(bg::detail::none_index_of<0>([&](auto) { return false; }) == true); } template @@ -60,7 +60,7 @@ void test_dimension(bg::util::index_constant) return bg::get(p) == 10; }) == false); BOOST_CHECK( - bg::detail::any_index_of<0>([&](auto index) + bg::detail::any_index_of<0>([&](auto) { return false; }) == false); @@ -70,7 +70,7 @@ void test_dimension(bg::util::index_constant) return bg::get(p) == double(I - 1); }) == true); BOOST_CHECK( - bg::detail::none_index_of<0>([&](auto index) + bg::detail::none_index_of<0>([&](auto) { return false; }) == true); From 3d8d40ee5cf122ae46dea7bbb59cc95ae5debc86 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 13 Aug 2021 19:03:37 +0200 Subject: [PATCH 35/74] [util] Add workaround for mismatched argument pack lengths error with gcc-11 c++20. --- include/boost/geometry/util/sequence.hpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/include/boost/geometry/util/sequence.hpp b/include/boost/geometry/util/sequence.hpp index 80e3b7b23..fad3d850e 100644 --- a/include/boost/geometry/util/sequence.hpp +++ b/include/boost/geometry/util/sequence.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2020, Oracle and/or its affiliates. +// Copyright (c) 2020-2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -187,13 +187,13 @@ struct combine; template struct combine, type_sequence> { - template - using type_sequence_t = type_sequence...>; + template + using type_sequence_t = type_sequence...>; - typedef typename merge + using type = typename merge < - type_sequence_t... - >::type type; + type_sequence_t... + >::type; }; // combine, integer_sequence>::type is @@ -202,13 +202,13 @@ struct combine, type_sequence> template struct combine, std::integer_sequence> { - template - using type_sequence_t = type_sequence...>; + template + using type_sequence_t = type_sequence...>; - typedef typename merge + using type = typename merge < - type_sequence_t... - >::type type; + type_sequence_t... + >::type; }; From 5f308236123de892d1bc838b6b26f596d95f91b2 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 13 Aug 2021 20:03:40 +0200 Subject: [PATCH 36/74] [util] Rename some of the sequence metafunctions. --- .../detail/select_geometry_type.hpp | 11 +- include/boost/geometry/util/sequence.hpp | 100 +++++++----------- 2 files changed, 48 insertions(+), 63 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/select_geometry_type.hpp b/include/boost/geometry/algorithms/detail/select_geometry_type.hpp index 2e94ae73e..fe89ed5ad 100644 --- a/include/boost/geometry/algorithms/detail/select_geometry_type.hpp +++ b/include/boost/geometry/algorithms/detail/select_geometry_type.hpp @@ -39,7 +39,7 @@ template template class LessPred > struct select_geometry_type - : util::select_element + : util::sequence_min_element < typename traits::geometry_types>::type, LessPred @@ -89,10 +89,13 @@ template template class LessPred > struct select_geometry_types - : util::select_combination_element + : util::sequence_min_element < - typename geometry_types::type, - typename geometry_types::type, + typename util::sequence_combine + < + typename geometry_types::type, + typename geometry_types::type + >::type, LessPred > {}; diff --git a/include/boost/geometry/util/sequence.hpp b/include/boost/geometry/util/sequence.hpp index fad3d850e..d8f70d734 100644 --- a/include/boost/geometry/util/sequence.hpp +++ b/include/boost/geometry/util/sequence.hpp @@ -62,13 +62,13 @@ struct sequence_element {}; template struct sequence_element> { - typedef typename sequence_element>::type type; + using type = typename sequence_element>::type; }; template struct sequence_element<0, type_sequence> { - typedef T type; + using type = T; }; template @@ -112,6 +112,7 @@ struct sequence_empty {}; +// Defines type member for the first type in sequence that satisfies UnaryPred. template < typename Sequence, @@ -138,77 +139,71 @@ template