$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r63988 - in sandbox/geometry: boost/geometry/strategies boost/geometry/strategies/cartesian boost/geometry/strategies/concepts boost/geometry/strategies/spherical libs/geometry/test/strategies
From: barend.gehrels_at_[hidden]
Date: 2010-07-13 14:48:45
Author: barendgehrels
Date: 2010-07-13 14:48:43 EDT (Tue, 13 Jul 2010)
New Revision: 63988
URL: http://svn.boost.org/trac/boost/changeset/63988
Log:
Applied new approach using function_types instead of member types to point-segment-distance strategies
Text files modified: 
   sandbox/geometry/boost/geometry/strategies/cartesian/distance_projected_point.hpp |    33 ++++-----                               
   sandbox/geometry/boost/geometry/strategies/concepts/distance_concept.hpp          |   130 ++++++++++++++++++++++++++------------- 
   sandbox/geometry/boost/geometry/strategies/distance.hpp                           |     3                                         
   sandbox/geometry/boost/geometry/strategies/spherical/distance_cross_track.hpp     |    29 ++++----                                
   sandbox/geometry/libs/geometry/test/strategies/projected_point.cpp                |     4                                         
   5 files changed, 120 insertions(+), 79 deletions(-)
Modified: sandbox/geometry/boost/geometry/strategies/cartesian/distance_projected_point.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/cartesian/distance_projected_point.hpp	(original)
+++ sandbox/geometry/boost/geometry/strategies/cartesian/distance_projected_point.hpp	2010-07-13 14:48:43 EDT (Tue, 13 Jul 2010)
@@ -65,18 +65,7 @@
 class projected_point
 {
 public :
-    typedef Point point_type;
-    typedef PointOfSegment segment_point_type;
-
-    typedef typename select_coordinate_type
-        <
-            Point,
-            PointOfSegment
-        >::type coordinate_type;
-
-    typedef typename strategy::distance::services::return_type<Strategy>::type return_type;
-
-    typedef Strategy point_strategy_type;
+    typedef typename strategy::distance::services::return_type<Strategy>::type calculation_type;
 
 private :
 
@@ -86,7 +75,7 @@
     // Integer coordinates can still result in FP distances.
     // There is a division, which must be represented in FP.
     // So promote.
-    typedef typename promote_floating_point<coordinate_type>::type fp_type;
+    typedef typename promote_floating_point<calculation_type>::type fp_type;
 
     // A projected point of points in Integer coordinates must be able to be
     // represented in FP.
@@ -105,14 +94,14 @@
     // So we create a "similar" one
     typedef typename strategy::distance::services::similar_type
         <
-            point_strategy_type,
+            Strategy,
             Point,
             fp_point_type
         >::type fp_strategy_type;
 
 public :
 
-    inline return_type apply(Point const& p,
+    inline calculation_type apply(Point const& p,
                     PointOfSegment const& p1, PointOfSegment const& p2) const
     {
         assert_dimension_equal<Point, PointOfSegment>();
@@ -135,10 +124,10 @@
         subtract_point(v, p1);
         subtract_point(w, p1);
 
-        point_strategy_type strategy;
+        Strategy strategy;
         boost::ignore_unused_variable_warning(strategy);
 
-        coordinate_type zero = coordinate_type();
+        calculation_type zero = calculation_type();
         fp_type c1 = dot_product(w, v);
         if (c1 <= zero)
         {
@@ -157,7 +146,7 @@
         fp_strategy_type fp_strategy
             = strategy::distance::services::get_similar
                 <
-                    point_strategy_type, Point, fp_point_type
+                    Strategy, Point, fp_point_type
                 >::apply(strategy);
 
         fp_point_type projected;
@@ -186,7 +175,13 @@
 template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
 struct return_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
 {
-    typedef typename projected_point<Point, PointOfSegment, CalculationType, Strategy>::return_type type;
+    typedef typename projected_point<Point, PointOfSegment, CalculationType, Strategy>::calculation_type type;
+};
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct strategy_point_point<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+    typedef typename Strategy type;
 };
 
 
Modified: sandbox/geometry/boost/geometry/strategies/concepts/distance_concept.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/concepts/distance_concept.hpp	(original)
+++ sandbox/geometry/boost/geometry/strategies/concepts/distance_concept.hpp	2010-07-13 14:48:43 EDT (Tue, 13 Jul 2010)
@@ -169,55 +169,95 @@
 struct PointSegmentDistanceStrategy
 {
 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
-    private :
+private :
 
-        // 1) must define point_type
-        typedef typename Strategy::point_type ptype;
-        BOOST_CONCEPT_ASSERT
-            (
-                (concept::ConstPoint<ptype>)
-            );
-
-        // 2) must define segment_point_type
-        typedef typename Strategy::segment_point_type sptype;
-        BOOST_CONCEPT_ASSERT
-            (
-                (concept::ConstPoint<sptype>)
-            );
-
-        // 3) must define meta-function return_type
-        typedef typename strategy::distance::services::return_type<Strategy>::type rtype;
-
-        // 4) must define underlying point-distance-strategy
-        typedef typename Strategy::point_strategy_type stype;
-        BOOST_CONCEPT_ASSERT
-            (
-                (concept::PointDistanceStrategy<stype>)
-            );
-
-
-        // 5) must implement method apply with arguments
-        struct apply_checker
+    struct checker
+    {
+        template <typename ApplyMethod>
+        static void apply(ApplyMethod const&)
         {
-            static void check()
-            {
-                Strategy *str;
-                ptype *p;
-                sptype *sp1;
-                sptype *sp2;
-
-                rtype r = str->apply(*p, *sp1, *sp2);
-
-                boost::ignore_unused_variable_warning(str);
-                boost::ignore_unused_variable_warning(r);
-            }
-        };
+            namespace ft = boost::function_types;
+            typedef typename ft::parameter_types
+                <
+                    ApplyMethod
+                >::type parameter_types;
+
+            typedef typename boost::mpl::if_
+                <
+                    ft::is_member_function_pointer<ApplyMethod>,
+                    boost::mpl::int_<1>,
+                    boost::mpl::int_<0>
+                >::type base_index;
+
+            // 1: inspect and define both arguments of apply
+            typedef typename boost::remove_const
+                <
+                    typename boost::remove_reference
+                        <
+                            typename boost::mpl::at
+                                <
+                                    parameter_types, 
+                                    base_index
+                                >::type
+                        >::type
+                >::type ptype;
+
+            typedef typename boost::remove_const
+                <
+                    typename boost::remove_reference
+                        <
+                            typename boost::mpl::at
+                                <
+                                    parameter_types, 
+                                    typename boost::mpl::plus
+                                        <
+                                            base_index, 
+                                            boost::mpl::int_<1> 
+                                        >::type
+                                >::type
+                        >::type
+                >::type sptype;
+
+            // 2) check if apply-arguments fulfill point concept 
+            BOOST_CONCEPT_ASSERT
+                (
+                    (concept::ConstPoint<ptype>)
+                );
+
+            BOOST_CONCEPT_ASSERT
+                (
+                    (concept::ConstPoint<sptype>)
+                );
+
+
+            // 3) must define meta-function return_type
+            typedef typename strategy::distance::services::return_type<Strategy>::type rtype;
+
+            // 4) must define underlying point-distance-strategy
+            typedef typename strategy::distance::services::strategy_point_point<Strategy>::type stype;
+            BOOST_CONCEPT_ASSERT
+                (
+                    (concept::PointDistanceStrategy<stype>)
+                );
+
+
+            Strategy *str;
+            ptype *p;
+            sptype *sp1;
+            sptype *sp2;
 
-    public :
-        BOOST_CONCEPT_USAGE(PointSegmentDistanceStrategy)
-        {
-            apply_checker::check();
+            rtype r = str->apply(*p, *sp1, *sp2);
+
+            boost::ignore_unused_variable_warning(str);
+            boost::ignore_unused_variable_warning(r);
         }
+    };
+
+public :
+    BOOST_CONCEPT_USAGE(PointSegmentDistanceStrategy)
+    {
+        checker::apply(&Strategy::apply);
+    }
 #endif
 };
 
Modified: sandbox/geometry/boost/geometry/strategies/distance.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/distance.hpp	(original)
+++ sandbox/geometry/boost/geometry/strategies/distance.hpp	2010-07-13 14:48:43 EDT (Tue, 13 Jul 2010)
@@ -52,6 +52,9 @@
 template <typename Strategy> struct result_from_distance {};
 
 
+// For point-segment only:
+template <typename Strategy> struct strategy_point_point {};
+
 
 // Default strategy
 
Modified: sandbox/geometry/boost/geometry/strategies/spherical/distance_cross_track.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/spherical/distance_cross_track.hpp	(original)
+++ sandbox/geometry/boost/geometry/strategies/spherical/distance_cross_track.hpp	2010-07-13 14:48:43 EDT (Tue, 13 Jul 2010)
@@ -60,18 +60,6 @@
                 >::type
         >::type return_type;
 
-    typedef Point point_type;
-    typedef PointOfSegment segment_point_type;
-
-    typedef Strategy point_strategy_type;
-
-    BOOST_CONCEPT_ASSERT
-        (
-            (geometry::concept::PointDistanceStrategy<point_strategy_type>)
-        );
-
-
-
     inline cross_track(return_type const& r = 1.0)
         : m_radius(r)
         , m_strategy(1.0) // Keep this 1.0 and not r
@@ -108,10 +96,16 @@
     inline return_type radius() const { return m_radius; }
 
 private :
+    BOOST_CONCEPT_ASSERT
+        (
+            (geometry::concept::PointDistanceStrategy<Strategy >)
+        );
+
+
     return_type m_radius;
 
     // Point-point distances are calculated in radians, on the unit sphere
-    point_strategy_type m_strategy;
+    Strategy m_strategy;
 
     /// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
     inline return_type course(Point const& p1, Point const& p2) const
@@ -226,6 +220,15 @@
     }
 };
 
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct strategy_point_point<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
+{
+    typedef typename Strategy type;
+};
+
+
+
 template <typename Point, typename PointOfSegment>
 struct default_strategy<segment_tag, Point, PointOfSegment, spherical_tag, spherical_tag>
 {
Modified: sandbox/geometry/libs/geometry/test/strategies/projected_point.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/strategies/projected_point.cpp	(original)
+++ sandbox/geometry/libs/geometry/test/strategies/projected_point.cpp	2010-07-13 14:48:43 EDT (Tue, 13 Jul 2010)
@@ -49,7 +49,7 @@
 
     BOOST_CONCEPT_ASSERT( (bg::concept::PointSegmentDistanceStrategy<strategy_type>) );
 
-    typedef typename strategy_type::return_type return_type;
+    typedef typename services::return_type<strategy_type>::type return_type;
 
     strategy_type strategy;
     return_type result = strategy.apply(p, p1, p2);
@@ -102,7 +102,7 @@
 
 
     strategy_type strategy;
-    typedef typename strategy_type::return_type return_type;
+    typedef typename bg::strategy::distance::services::return_type<strategy_type>::type return_type;
     return_type d = strategy.apply(p, sp1, sp2);
     BOOST_CHECK_CLOSE(d, return_type(0.27735203958327), 0.001);
 }