]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/geometry/algorithms/detail/distance/segment_to_box.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / distance / segment_to_box.hpp
index 1f381970d8e6482e0da91f37fb81c70f32fd3d7a..354d42bd01173eb4afeea211ee6d40ba52ecfeb8 100644 (file)
@@ -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 Vissarion Fysikopoulos, on behalf of Oracle
 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
 #include <boost/core/ignore_unused.hpp>
 #include <boost/numeric/conversion/cast.hpp>
 
-#include <boost/geometry/core/access.hpp>
-#include <boost/geometry/core/assert.hpp>
-#include <boost/geometry/core/closure.hpp>
-#include <boost/geometry/core/coordinate_dimension.hpp>
-#include <boost/geometry/core/point_type.hpp>
-#include <boost/geometry/core/tags.hpp>
-
 #include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
 #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
 #include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
 #include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
-#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
 #include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
+#include <boost/geometry/algorithms/detail/distance/strategy_utils.hpp>
+#include <boost/geometry/algorithms/detail/dummy_geometries.hpp>
 #include <boost/geometry/algorithms/detail/equals/point_point.hpp>
 #include <boost/geometry/algorithms/dispatch/distance.hpp>
 #include <boost/geometry/algorithms/not_implemented.hpp>
 
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
 #include <boost/geometry/policies/compare.hpp>
 
 #include <boost/geometry/util/calculation_type.hpp>
@@ -48,7 +49,6 @@
 #include <boost/geometry/strategies/distance.hpp>
 #include <boost/geometry/strategies/tags.hpp>
 
-
 namespace boost { namespace geometry
 {
 
@@ -58,26 +58,24 @@ namespace detail { namespace distance
 {
 
 
-// TODO: Take strategy
-template <typename Segment, typename Box>
-inline bool intersects_segment_box(Segment const& segment, Box const& box)
+template <typename Segment, typename Box, typename Strategy>
+inline bool intersects_segment_box(Segment const& segment, Box const& box,
+                                   Strategy const& strategy)
 {
-    typedef typename strategy::disjoint::services::default_strategy
-        <
-            Segment, Box
-        >::type strategy_type;
-
-    return ! detail::disjoint::disjoint_segment_box::apply(segment, box,
-                                                           strategy_type());
+    return ! detail::disjoint::disjoint_segment_box::apply(segment, box, strategy);
 }
 
+// TODO: segment_to_box_2D_generic is not used anymore. Remove?
+
+// TODO: Furthermore this utility can potentially use different strategy than
+//       the one that was passed into bg::distance() but it seems this is by design.
 
 template
 <
     typename Segment,
     typename Box,
-    typename Strategy,
-    bool UsePointBoxStrategy = false
+    typename Strategies,
+    bool UsePointBoxStrategy = false // use only PointSegment strategy
 >
 class segment_to_box_2D_generic
 {
@@ -85,46 +83,29 @@ private:
     typedef typename point_type<Segment>::type segment_point;
     typedef typename point_type<Box>::type box_point;
 
-    typedef typename strategy::distance::services::comparable_type
-        <
-            typename Strategy::distance_ps_strategy::type
-        >::type comparable_strategy;
+    typedef distance::strategy_t<box_point, Segment, Strategies> ps_strategy_type;
 
     typedef detail::closest_feature::point_to_point_range
         <
             segment_point,
             std::vector<box_point>,
-            open,
-            comparable_strategy
+            open
         > point_to_point_range;
-
-    typedef typename strategy::distance::services::return_type
-        <
-            comparable_strategy, segment_point, box_point
-        >::type comparable_return_type;
     
 public:
-    typedef typename strategy::distance::services::return_type
-        <
-            Strategy, segment_point, box_point
-        >::type return_type;
+    // TODO: Or should the return type be defined by sb_strategy_type?
+    typedef distance::return_t<box_point, Segment, Strategies> return_type;
 
     static inline return_type apply(Segment const& segment,
                                     Box const& box,
-                                    Strategy const& strategy,
+                                    Strategies const& strategies,
                                     bool check_intersection = true)
     {
-        if (check_intersection && intersects_segment_box(segment, box))
+        if (check_intersection && intersects_segment_box(segment, box, strategies))
         {
-            return 0;
+            return return_type(0);
         }
 
-        comparable_strategy cstrategy =
-            strategy::distance::services::get_comparable
-                <
-                    typename Strategy::distance_ps_strategy::type
-                >::apply(strategy.get_distance_ps_strategy());
-
         // get segment points
         segment_point p[2];
         detail::assign_point_from_index<0>(segment, p[0]);
@@ -134,7 +115,14 @@ public:
         std::vector<box_point> box_points(4);
         detail::assign_box_corners_oriented<true>(box, box_points);
  
-        comparable_return_type cd[6];
+        ps_strategy_type const strategy = strategies.distance(dummy_point(), dummy_segment());
+
+        auto const cstrategy = strategy::distance::services::get_comparable
+                                <
+                                    ps_strategy_type
+                                >::apply(strategy);
+
+        distance::creturn_t<box_point, Segment, Strategies> cd[6];
         for (unsigned int i = 0; i < 4; ++i)
         {
             cd[i] = cstrategy.apply(box_points[i], p[0], p[1]);
@@ -166,19 +154,19 @@ public:
             }
         }
 
-        if (BOOST_GEOMETRY_CONDITION(is_comparable<Strategy>::value))
+        if (BOOST_GEOMETRY_CONDITION(is_comparable<ps_strategy_type>::value))
         {
             return cd[imin];
         }
 
         if (imin < 4)
         {
-            return strategy.get_distance_ps_strategy().apply(box_points[imin], p[0], p[1]);
+            return strategy.apply(box_points[imin], p[0], p[1]);
         }
         else
         {
             unsigned int bimin = imin - 4;
-            return strategy.get_distance_ps_strategy().apply(p[bimin],
+            return strategy.apply(p[bimin],
                                   *bit_min[bimin].first,
                                   *bit_min[bimin].second);
         }
@@ -190,57 +178,31 @@ template
 <
     typename Segment,
     typename Box,
-    typename Strategy
+    typename Strategies
 >
-class segment_to_box_2D_generic<Segment, Box, Strategy, true>
+class segment_to_box_2D_generic<Segment, Box, Strategies, true> // Use both PointSegment and PointBox strategies
 {
 private:
     typedef typename point_type<Segment>::type segment_point;
     typedef typename point_type<Box>::type box_point;
 
-    typedef typename strategy::distance::services::comparable_type
-        <
-            Strategy
-        >::type comparable_strategy;
-
-    typedef typename strategy::distance::services::return_type
-        <
-            comparable_strategy, segment_point, box_point
-        >::type comparable_return_type;
-
-    typedef typename detail::distance::default_strategy
-        <
-            segment_point, Box
-        >::type point_box_strategy;
-
-    typedef typename strategy::distance::services::comparable_type
-        <
-            point_box_strategy
-        >::type point_box_comparable_strategy;
+    typedef distance::strategy_t<box_point, Segment, Strategies> ps_strategy_type;
+    typedef distance::strategy_t<segment_point, Box, Strategies> pb_strategy_type;
 
 public:
-    typedef typename strategy::distance::services::return_type
-        <
-            Strategy, segment_point, box_point
-        >::type return_type;
-
+    // TODO: Or should the return type be defined by sb_strategy_type?
+    typedef distance::return_t<box_point, Segment, Strategies> return_type;
+    
     static inline return_type apply(Segment const& segment,
                                     Box const& box,
-                                    Strategy const& strategy,
+                                    Strategies const& strategies,
                                     bool check_intersection = true)
     {
-        if (check_intersection && intersects_segment_box(segment, box))
+        if (check_intersection && intersects_segment_box(segment, box, strategies))
         {
-            return 0;
+            return return_type(0);
         }
 
-        comparable_strategy cstrategy =
-            strategy::distance::services::get_comparable
-                <
-                    Strategy
-                >::apply(strategy);
-        boost::ignore_unused(cstrategy);
-
         // get segment points
         segment_point p[2];
         detail::assign_point_from_index<0>(segment, p[0]);
@@ -249,15 +211,28 @@ public:
         // get box points
         std::vector<box_point> box_points(4);
         detail::assign_box_corners_oriented<true>(box, box_points);
-        comparable_return_type cd[6];
+
+        distance::creturn_t<box_point, Segment, Strategies> cd[6];
+
+        ps_strategy_type ps_strategy = strategies.distance(dummy_point(), dummy_segment());
+        auto const ps_cstrategy = strategy::distance::services::get_comparable
+                                    <
+                                        ps_strategy_type
+                                    >::apply(ps_strategy);
+        boost::ignore_unused(ps_strategy, ps_cstrategy);
+
         for (unsigned int i = 0; i < 4; ++i)
         {
-            cd[i] = cstrategy.apply(box_points[i], p[0], p[1]);
+            cd[i] = ps_cstrategy.apply(box_points[i], p[0], p[1]);
         }
 
-        point_box_comparable_strategy pb_cstrategy;
-        boost::ignore_unused(pb_cstrategy);
+        pb_strategy_type const pb_strategy = strategies.distance(dummy_point(), dummy_box());
+        auto const pb_cstrategy = strategy::distance::services::get_comparable
+                                    <
+                                        pb_strategy_type
+                                    >::apply(pb_strategy);
+        boost::ignore_unused(pb_strategy, pb_cstrategy);
+
         cd[4] = pb_cstrategy.apply(p[0], box);
         cd[5] = pb_cstrategy.apply(p[1], box);
 
@@ -270,18 +245,23 @@ public:
             }
         }
 
-        if (is_comparable<Strategy>::value)
-        {
-            return cd[imin];
-        }
-
         if (imin < 4)
         {
-            strategy.apply(box_points[imin], p[0], p[1]);
+            if (is_comparable<ps_strategy_type>::value)
+            {
+                return cd[imin];
+            }
+
+            return ps_strategy.apply(box_points[imin], p[0], p[1]);
         }
         else
         {
-            return point_box_strategy().apply(p[imin - 4], box);
+            if (is_comparable<pb_strategy_type>::value)
+            {
+                return cd[imin];
+            }
+
+            return pb_strategy.apply(p[imin - 4], box);
         }
     }
 };
@@ -294,7 +274,7 @@ template
     typename ReturnType,
     typename SegmentPoint,
     typename BoxPoint,
-    typename SBStrategy
+    typename Strategies
 >
 class segment_to_box_2D
 {
@@ -353,10 +333,8 @@ private:
                                        SegmentPoint const& p1,
                                        BoxPoint const& bottom_right,
                                        BoxPoint const& top_right,
-                                       SBStrategy const& sb_strategy)
+                                       Strategies const& strategies)
         {
-            boost::ignore_unused(sb_strategy);
-
             // the implementation below is written for non-negative slope
             // segments
             //
@@ -367,8 +345,7 @@ private:
 
             LessEqual less_equal;
 
-            typename SBStrategy::distance_ps_strategy::type ps_strategy =
-                                sb_strategy.get_distance_ps_strategy();
+            auto const ps_strategy = strategies.distance(dummy_point(), dummy_segment());
 
             if (less_equal(geometry::get<1>(bottom_right), geometry::get<1>(p0)))
             {
@@ -410,19 +387,19 @@ private:
         static inline ReturnType apply(SegmentPoint const& p0,
                                        SegmentPoint const& p1,
                                        BoxPoint const& top_left,
-                                       SBStrategy const& sb_strategy)
+                                       Strategies const& strategies)
         {
-            boost::ignore_unused(sb_strategy);
-            return apply(p0, p1, p0, top_left, sb_strategy);
+            return apply(p0, p1, p0, top_left, strategies);
         }
 
         static inline ReturnType apply(SegmentPoint const& p0,
                                        SegmentPoint const& p1,
                                        SegmentPoint const& p_max,
                                        BoxPoint const& top_left,
-                                       SBStrategy const& sb_strategy)
+                                       Strategies const& strategies)
         {
-            boost::ignore_unused(sb_strategy);
+            auto const ps_strategy = strategies.distance(dummy_point(), dummy_segment());
+
             typedef cast_to_result<ReturnType> cast;
             LessEqual less_equal;
 
@@ -430,22 +407,21 @@ private:
             // then compute the vertical (i.e. meridian for spherical) distance
             if (less_equal(geometry::get<0>(top_left), geometry::get<0>(p_max)))
             {
-                ReturnType diff =
-                sb_strategy.get_distance_ps_strategy().vertical_or_meridian(
+                ReturnType diff = ps_strategy.vertical_or_meridian(
                                     geometry::get_as_radian<1>(p_max),
                                     geometry::get_as_radian<1>(top_left));
 
                 return strategy::distance::services::result_from_distance
                     <
-                        SBStrategy, SegmentPoint, BoxPoint
-                    >::apply(sb_strategy, math::abs(diff));
+                        std::remove_const_t<decltype(ps_strategy)>,
+                        SegmentPoint, BoxPoint
+                    >::apply(ps_strategy, math::abs(diff));
             }
 
             // p0 is to the left of the box, but p1 is above the box
             // in this case the distance is realized between the
             // top-left corner of the box and the segment
-            return cast::apply(sb_strategy.get_distance_ps_strategy().
-                                                      apply(top_left, p0, p1));
+            return cast::apply(ps_strategy.apply(top_left, p0, p1));
         }
     };
 
@@ -458,7 +434,7 @@ private:
                                  BoxPoint const& top_right,
                                  BoxPoint const& bottom_left,
                                  BoxPoint const& bottom_right,
-                                 SBStrategy const& sb_strategy,
+                                 Strategies const& strategies,
                                  ReturnType& result)
         {
             // p0 lies to the right of the box
@@ -468,7 +444,7 @@ private:
                     <
                         LessEqual
                     >::apply(p0, p1, bottom_right, top_right,
-                             sb_strategy);
+                             strategies);
                 return true;
             }
 
@@ -479,7 +455,7 @@ private:
                     <
                         typename other_compare<LessEqual>::type
                     >::apply(p1, p0, top_left, bottom_left,
-                             sb_strategy);
+                             strategies);
                 return true;
             }
 
@@ -496,7 +472,7 @@ private:
                                  BoxPoint const& top_right,
                                  BoxPoint const& bottom_left,
                                  BoxPoint const& bottom_right,
-                                 SBStrategy const& sb_strategy,
+                                 Strategies const& strategies,
                                  ReturnType& result)
         {
             typedef compare_less_equal<ReturnType, false> GreaterEqual;
@@ -504,13 +480,20 @@ private:
             // the segment lies below the box
             if (geometry::get<1>(p1) < geometry::get<1>(bottom_left))
             {
+                auto const sb_strategy = strategies.distance(dummy_segment(), dummy_box());
+
+                // TODO: this strategy calls this algorithm's again, specifically:
+                //       geometry::detail::distance::segment_to_box_2D<>::call_above_of_box
+                //       If possible rewrite them to avoid this.
+                //       For now just pass umbrella strategy.
                 result = sb_strategy.template segment_below_of_box
                         <
                             LessEqual,
                             ReturnType
                         >(p0, p1,
                           top_left, top_right,
-                          bottom_left, bottom_right);
+                          bottom_left, bottom_right,
+                          strategies);
                 return true;
             }
 
@@ -520,11 +503,11 @@ private:
                 result = (std::min)(above_of_box
                                     <
                                         LessEqual
-                                    >::apply(p0, p1, top_left, sb_strategy),
+                                    >::apply(p0, p1, top_left, strategies),
                                     above_of_box
                                     <
                                         GreaterEqual
-                                    >::apply(p1, p0, top_right, sb_strategy));
+                                    >::apply(p1, p0, top_right, strategies));
                 return true;
             }
             return false;
@@ -537,19 +520,16 @@ private:
                                  SegmentPoint const& p1,
                                  BoxPoint const& corner1,
                                  BoxPoint const& corner2,
-                                 SBStrategy const& sb_strategy,
+                                 Strategies const& strategies,
                                  ReturnType& result)
         {
-            typename SBStrategy::side_strategy_type
-                side_strategy = sb_strategy.get_side_strategy();
+            auto const side_strategy = strategies.side();
+            auto const ps_strategy = strategies.distance(dummy_point(), dummy_segment());
 
             typedef cast_to_result<ReturnType> cast;
             ReturnType diff1 = cast::apply(geometry::get<1>(p1))
                                - cast::apply(geometry::get<1>(p0));
 
-            typename SBStrategy::distance_ps_strategy::type ps_strategy =
-                                sb_strategy.get_distance_ps_strategy();
-
             int sign = diff1 < 0 ? -1 : 1;
             if (side_strategy.apply(p0, p1, corner1) * sign < 0)
             {
@@ -572,7 +552,7 @@ private:
                                BoxPoint const& top_right,
                                BoxPoint const& bottom_left,
                                BoxPoint const& bottom_right,
-                               SBStrategy const& sb_strategy)
+                               Strategies const& strategies)
     {
         typedef compare_less_equal<ReturnType, true> less_equal;
 
@@ -592,7 +572,7 @@ private:
                     less_equal
                 >::apply(p0, p1,
                          top_left, top_right, bottom_left, bottom_right,
-                         sb_strategy, result))
+                         strategies, result))
         {
             return result;
         }
@@ -602,14 +582,14 @@ private:
                     less_equal
                 >::apply(p0, p1,
                          top_left, top_right, bottom_left, bottom_right,
-                         sb_strategy, result))
+                         strategies, result))
         {
             return result;
         }
 
         if (check_generic_position::apply(p0, p1,
                                           top_left, bottom_right,
-                                          sb_strategy, result))
+                                          strategies, result))
         {
             return result;
         }
@@ -626,7 +606,7 @@ private:
                            BoxPoint const& top_right,
                            BoxPoint const& bottom_left,
                            BoxPoint const& bottom_right,
-                           SBStrategy const& sb_strategy)
+                           Strategies const& strategies)
     {
         typedef compare_less_equal<ReturnType, false> greater_equal;
 
@@ -643,7 +623,7 @@ private:
                     greater_equal
                 >::apply(p0, p1,
                          bottom_left, bottom_right, top_left, top_right,
-                         sb_strategy, result))
+                         strategies, result))
         {
             return result;
         }
@@ -653,14 +633,14 @@ private:
                     greater_equal
                 >::apply(p1, p0,
                          top_right, top_left, bottom_right, bottom_left,
-                         sb_strategy, result))
+                         strategies, result))
         {
             return result;
         }
 
         if (check_generic_position::apply(p0, p1,
                                           bottom_left, top_right,
-                                          sb_strategy, result))
+                                          strategies, result))
         {
             return result;
         }
@@ -676,9 +656,9 @@ public:
                                    BoxPoint const& top_right,
                                    BoxPoint const& bottom_left,
                                    BoxPoint const& bottom_right,
-                                   SBStrategy const& sb_strategy)
+                                   Strategies const& strategies)
     {
-        BOOST_GEOMETRY_ASSERT( (geometry::less<SegmentPoint, -1, typename SBStrategy::cs_tag>()(p0, p1))
+        BOOST_GEOMETRY_ASSERT( (geometry::less<SegmentPoint, -1, typename Strategies::cs_tag>()(p0, p1))
                             || geometry::has_nan_coordinate(p0)
                             || geometry::has_nan_coordinate(p1) );
 
@@ -688,13 +668,13 @@ public:
             return negative_slope_segment(p0, p1,
                                           top_left, top_right,
                                           bottom_left, bottom_right,
-                                          sb_strategy);
+                                          strategies);
         }
 
         return non_negative_slope_segment(p0, p1,
                                           top_left, top_right,
                                           bottom_left, bottom_right,
-                                          sb_strategy);
+                                          strategies);
     }
 
     template <typename LessEqual>
@@ -702,18 +682,18 @@ public:
                                                SegmentPoint const& p1,
                                                SegmentPoint const& p_max,
                                                BoxPoint const& top_left,
-                                               SBStrategy const& sb_strategy)
+                                               Strategies const& strategies)
     {
-        return above_of_box<LessEqual>::apply(p0, p1, p_max, top_left, sb_strategy);
+        return above_of_box<LessEqual>::apply(p0, p1, p_max, top_left, strategies);
     }
 
     template <typename LessEqual>
     static inline ReturnType call_above_of_box(SegmentPoint const& p0,
                                                SegmentPoint const& p1,
                                                BoxPoint const& top_left,
-                                               SBStrategy const& sb_strategy)
+                                               Strategies const& strategies)
     {
-        return above_of_box<LessEqual>::apply(p0, p1, top_left, sb_strategy);
+        return above_of_box<LessEqual>::apply(p0, p1, top_left, strategies);
     }
 };
 
@@ -724,7 +704,7 @@ template
     typename Segment,
     typename Box,
     typename std::size_t Dimension,
-    typename SBStrategy
+    typename Strategies
 >
 class segment_to_box
     : not_implemented<Segment, Box>
@@ -735,71 +715,45 @@ template
 <
     typename Segment,
     typename Box,
-    typename SBStrategy
+    typename Strategies
 >
-class segment_to_box<Segment, Box, 2, SBStrategy>
+class segment_to_box<Segment, Box, 2, Strategies>
 {
-private:
-    typedef typename point_type<Segment>::type segment_point;
-    typedef typename point_type<Box>::type box_point;
-
-    typedef typename strategy::distance::services::comparable_type
-        <
-            SBStrategy
-        >::type ps_comparable_strategy;
+    typedef distance::strategy_t<Segment, Box, Strategies> strategy_type;
 
-    typedef typename strategy::distance::services::return_type
-        <
-            ps_comparable_strategy, segment_point, box_point
-        >::type comparable_return_type;
 public:
-    typedef typename strategy::distance::services::return_type
-        <
-            SBStrategy, segment_point, box_point
-        >::type return_type;
+    typedef distance::return_t<Segment, Box, Strategies> return_type;
 
     static inline return_type apply(Segment const& segment,
                                     Box const& box,
-                                    SBStrategy const& sb_strategy)
+                                    Strategies const& strategies)
     {
+        typedef typename point_type<Segment>::type segment_point;
+        typedef typename point_type<Box>::type box_point;
+
         segment_point p[2];
         detail::assign_point_from_index<0>(segment, p[0]);
         detail::assign_point_from_index<1>(segment, p[1]);
 
-        if (detail::equals::equals_point_point(p[0], p[1],
-                sb_strategy.get_equals_point_point_strategy()))
+        if (detail::equals::equals_point_point(p[0], p[1], strategies))
         {
-            typedef std::conditional_t
-                <
-                    std::is_same
-                        <
-                            ps_comparable_strategy,
-                            SBStrategy
-                        >::value,
-                    typename strategy::distance::services::comparable_type
-                        <
-                            typename SBStrategy::distance_pb_strategy::type
-                        >::type,
-                    typename SBStrategy::distance_pb_strategy::type
-                > point_box_strategy_type;
-
             return dispatch::distance
                 <
                     segment_point,
                     Box,
-                    point_box_strategy_type
-                >::apply(p[0], box, point_box_strategy_type());
+                    Strategies
+                >::apply(p[0], box, strategies);
         }
 
         box_point top_left, top_right, bottom_left, bottom_right;
         detail::assign_box_corners(box, bottom_left, bottom_right,
                                    top_left, top_right);
 
-        SBStrategy::mirror(p[0], p[1],
-                           bottom_left, bottom_right,
-                           top_left, top_right);
+        strategy_type::mirror(p[0], p[1],
+                              bottom_left, bottom_right,
+                              top_left, top_right);
 
-        typedef geometry::less<segment_point, -1, typename SBStrategy::cs_tag> less_type;
+        typedef geometry::less<segment_point, -1, typename Strategies::cs_tag> less_type;
         if (less_type()(p[0], p[1]))
         {
             return segment_to_box_2D
@@ -807,10 +761,10 @@ public:
                     return_type,
                     segment_point,
                     box_point,
-                    SBStrategy
+                    Strategies
                 >::apply(p[0], p[1],
                          top_left, top_right, bottom_left, bottom_right,
-                         sb_strategy);
+                         strategies);
         }
         else
         {
@@ -819,10 +773,10 @@ public:
                     return_type,
                     segment_point,
                     box_point,
-                    SBStrategy
+                    Strategies
                 >::apply(p[1], p[0],
                          top_left, top_right, bottom_left, bottom_right,
-                         sb_strategy);
+                         strategies);
         }
     }
 };
@@ -837,24 +791,15 @@ namespace dispatch
 {
 
 
-template <typename Segment, typename Box, typename Strategy>
+template <typename Segment, typename Box, typename Strategies>
 struct distance
     <
-        Segment, Box, Strategy, segment_tag, box_tag,
+        Segment, Box, Strategies, segment_tag, box_tag,
         strategy_tag_distance_segment_box, false
     >
 {
-    typedef typename strategy::distance::services::return_type
-        <
-            Strategy,
-            typename point_type<Segment>::type,
-            typename point_type<Box>::type
-        >::type return_type;
-
-
-    static inline return_type apply(Segment const& segment,
-                                    Box const& box,
-                                    Strategy const& strategy)
+    static inline auto apply(Segment const& segment, Box const& box,
+                             Strategies const& strategies)
     {
         assert_dimension_equal<Segment, Box>();
 
@@ -863,8 +808,8 @@ struct distance
                 Segment,
                 Box,
                 dimension<Segment>::value,
-                Strategy
-            >::apply(segment, box, strategy);
+                Strategies
+            >::apply(segment, box, strategies);
     }
 };