$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r73177 - in trunk/boost/geometry: algorithms core multi/algorithms multi/core strategies strategies/agnostic strategies/cartesian strategies/concepts util
From: barend.gehrels_at_[hidden]
Date: 2011-07-17 08:26:03
Author: barendgehrels
Date: 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
New Revision: 73177
URL: http://svn.boost.org/trac/boost/changeset/73177
Log:
Added a "covered_by" algorithm (= within or on border)
Revised point-in-box, box-in-box, now with strategies
Therefore, revised within strategy.
Also adapted concept for within, and refactored getting parameters into parameter_type_of (also used by distance concept)
To avoid specifying default strategies again and again for all spherical coordinate systems, used the spherical_tag as the parent for spherical_polar_tag, spherical_equatorial_tag, geographic_tag
Added:
   trunk/boost/geometry/algorithms/covered_by.hpp   (contents, props changed)
   trunk/boost/geometry/multi/algorithms/covered_by.hpp   (contents, props changed)
   trunk/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp   (contents, props changed)
   trunk/boost/geometry/strategies/cartesian/box_in_box.hpp   (contents, props changed)
   trunk/boost/geometry/strategies/cartesian/point_in_box.hpp   (contents, props changed)
   trunk/boost/geometry/strategies/covered_by.hpp   (contents, props changed)
   trunk/boost/geometry/util/parameter_type_of.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/geometry/algorithms/within.hpp                         |   410 ++++++++------------------------------- 
   trunk/boost/geometry/core/tags.hpp                                 |    16 +                                       
   trunk/boost/geometry/multi/algorithms/within.hpp                   |    43 ++-                                     
   trunk/boost/geometry/multi/core/tags.hpp                           |     2                                         
   trunk/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp |    41 ++-                                     
   trunk/boost/geometry/strategies/concepts/distance_concept.hpp      |    75 ------                                  
   trunk/boost/geometry/strategies/concepts/within_concept.hpp        |   255 ++++++++++++++++++++++--                
   trunk/boost/geometry/strategies/strategies.hpp                     |     3                                         
   trunk/boost/geometry/strategies/within.hpp                         |    23 +                                       
   9 files changed, 416 insertions(+), 452 deletions(-)
Added: trunk/boost/geometry/algorithms/covered_by.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/algorithms/covered_by.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,206 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// 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_COVERED_BY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
+
+
+#include <cstddef>
+
+
+#include <boost/geometry/algorithms/within.hpp>
+
+
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
+#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag1,
+    typename Tag2,
+    typename Geometry1,
+    typename Geometry2,
+    typename Strategy
+>
+struct covered_by
+{
+    BOOST_MPL_ASSERT_MSG
+        (
+            false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+            , (types<Geometry1, Geometry2>)
+        );
+};
+
+
+template <typename Point, typename Box, typename Strategy>
+struct covered_by<point_tag, box_tag, Point, Box, Strategy>
+{
+    static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
+    {
+        return strategy.apply(point, box);
+    }
+};
+
+template <typename Box1, typename Box2, typename Strategy>
+struct covered_by<box_tag, box_tag, Box1, Box2, Strategy>
+{
+    static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
+    {
+        assert_dimension_equal<Box1, Box2>();
+        return strategy.apply(box1, box2);
+    }
+};
+
+
+
+template <typename Point, typename Ring, typename Strategy>
+struct covered_by<point_tag, ring_tag, Point, Ring, Strategy>
+{
+    static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
+    {
+        return detail::within::point_in_ring
+            <
+                Point,
+                Ring,
+                order_as_direction<geometry::point_order<Ring>::value>::value,
+                geometry::closure<Ring>::value,
+                Strategy
+            >::apply(point, ring) >= 0;
+    }
+};
+
+template <typename Point, typename Polygon, typename Strategy>
+struct covered_by<point_tag, polygon_tag, Point, Polygon, Strategy>
+{
+    static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
+    {
+        return detail::within::point_in_polygon
+        <
+            Point,
+            Polygon,
+            order_as_direction<geometry::point_order<Polygon>::value>::value,
+            geometry::closure<Polygon>::value,
+            Strategy
+        >::apply(point, polygon, strategy) >= 0;
+    }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_check12{is inside or on border}
+\ingroup covered_by
+\details \details_check12{covered_by, is inside or on border}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param geometry1 geometry which might be covered_by the second geometry
+\param geometry2 geometry which might contain the first geometry
+\return true if geometry1 is completely contained covered_by geometry2,
+    else false
+\note The default strategy is used for covered_by detection
+
+ */
+template<typename Geometry1, typename Geometry2>
+inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+    concept::check<Geometry1 const>();
+    concept::check<Geometry2 const>();
+    assert_dimension_equal<Geometry1, Geometry2>();
+
+    typedef typename point_type<Geometry1>::type point_type1;
+    typedef typename point_type<Geometry2>::type point_type2;
+
+    typedef typename strategy::covered_by::services::default_strategy
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            typename tag<Geometry1>::type,
+            typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+            typename tag_cast
+                <
+                    typename cs_tag<point_type1>::type, spherical_tag
+                >::type,
+            typename tag_cast
+                <
+                    typename cs_tag<point_type2>::type, spherical_tag
+                >::type,
+            Geometry1,
+            Geometry2
+        >::type strategy_type;
+
+    return dispatch::covered_by
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            Geometry1,
+            Geometry2,
+            strategy_type
+        >::apply(geometry1, geometry2, strategy_type());
+}
+
+/*!
+\brief \brief_check12{is inside or on border} \brief_strategy
+\ingroup covered_by
+\details \details_check12{covered_by, is inside or on border}, \brief_strategy. \details_strategy_reasons
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param geometry1 \param_geometry geometry which might be covered_by the second geometry
+\param geometry2 \param_geometry which might contain the first geometry
+\param strategy strategy to be used
+\return true if geometry1 is completely contained covered_by geometry2,
+    else false
+
+\qbk{distinguish,with strategy}
+
+*/
+template<typename Geometry1, typename Geometry2, typename Strategy>
+inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2,
+        Strategy const& strategy)
+{
+	concept::within::check
+        <
+            typename tag<Geometry1>::type, 
+            typename tag<Geometry2>::type, 
+            typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+            Strategy
+        >();
+    concept::check<Geometry1 const>();
+    concept::check<Geometry2 const>();
+    assert_dimension_equal<Geometry1, Geometry2>();
+
+    return dispatch::covered_by
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            Geometry1,
+            Geometry2,
+            Strategy
+        >::apply(geometry1, geometry2, strategy);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
Modified: trunk/boost/geometry/algorithms/within.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/within.hpp	(original)
+++ trunk/boost/geometry/algorithms/within.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -31,6 +31,7 @@
 #include <boost/geometry/core/point_order.hpp>
 #include <boost/geometry/core/ring_type.hpp>
 #include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tags.hpp>
 
 #include <boost/geometry/geometries/concepts/check.hpp>
 #include <boost/geometry/strategies/within.hpp>
@@ -49,201 +50,6 @@
 {
 
 
-struct within_state
-{
-    bool outside, inside, on_border;
-    inline within_state()
-        : outside(false)
-        , on_border(false)
-    {}
-
-    inline int code() const
-    {
-        // Note the order: 1) outside 2) on_border 3) inside
-        // If one dim. is outside, it IS outside, else
-        // if one dim is on border, it IS on border,
-        // if it only inside if inside=true and the rest is false
-        return outside ? -1
-            : on_border ? 0
-            : 1
-            ;
-    }
-
-};
-
-/*!
-    \brief Implementation for boxes
-    \ingroup boolean_relations
-    \note Should have strategy for e.g. Wrangel
- */
-template
-<
-    typename Point,
-    typename Box,
-    typename Strategy,
-    std::size_t Dimension,
-    std::size_t DimensionCount
->
-struct point_in_box_helper
-{
-    static inline void apply(Point const& p, Box const& b, Strategy const& s, within_state& state)
-    {
-        typename geometry::coordinate_type<Point>::type const v
-                    = get<Dimension>(p);
-        typename geometry::coordinate_type<Box>::type const b_min
-                    = get<min_corner, Dimension>(b);
-        typename geometry::coordinate_type<Box>::type const b_max
-                    = get<max_corner, Dimension>(b);
-                    
-        if (geometry::math::equals(v, b_min) 
-                || geometry::math::equals(v, b_max))
-        {
-            state.on_border = true;
-        }
-        else if (v < b_min || v > b_max)
-        {
-            state.outside = true;
-            return;
-        }
-        
-        point_in_box_helper
-            <
-                Point,
-                Box,
-                Strategy,
-                Dimension + 1,
-                DimensionCount
-            >::apply(p, b, s, state);
-    }
-};
-
-template
-<
-    typename Point,
-    typename Box,
-    typename Strategy,
-    std::size_t DimensionCount
->
-struct point_in_box_helper<Point, Box, Strategy, DimensionCount, DimensionCount>
-{
-    static inline void apply(Point const& , Box const& , Strategy const&, within_state& )
-    {
-    }
-};
-
-template
-<
-    typename Point,
-    typename Box,
-    typename Strategy
->
-struct point_in_box
-{
-    static inline int apply(Point const& point, Box const& box, Strategy const& strategy)
-    {
-        assert_dimension_equal<Point, Box>();
-        within_state state;
-        point_in_box_helper
-            <
-                Point, Box, Strategy, 
-                0, dimension<Point>::type::value
-            >::apply(point, box, strategy, state);
-        return state.code();
-    }
-};
-
-
-template
-<
-    typename Box1,
-    typename Box2,
-    typename Strategy,
-    std::size_t Dimension,
-    std::size_t DimensionCount
->
-struct box_in_box_helper
-{
-    static inline void apply(Box1 const& b_contained, Box2 const& b_containing,
-                Strategy const& strategy, within_state& state)
-    {
-        assert_dimension_equal<Box1, Box2>();
-
-        typename geometry::coordinate_type<Box1>::type const ced_min
-                    = get<min_corner, Dimension>(b_contained);
-        typename geometry::coordinate_type<Box1>::type const ced_max
-                    = get<max_corner, Dimension>(b_contained);
-        typename geometry::coordinate_type<Box2>::type const cing_min
-                    = get<min_corner, Dimension>(b_containing);
-        typename geometry::coordinate_type<Box2>::type const cing_max
-                    = get<max_corner, Dimension>(b_containing);
-
-        if (geometry::math::equals(ced_min, cing_min))
-        {
-            state.on_border = true;
-        }
-        else if (ced_min < cing_min)
-        {
-            state.outside = true;
-            return;
-        }
-
-        if (geometry::math::equals(ced_max, cing_max))
-        {
-            state.on_border = true;
-        }
-        else if (ced_max > cing_max)
-        {
-            state.outside = true;
-            return;
-        }
-
-        box_in_box_helper
-            <
-                Box1,
-                Box2,
-                Strategy,
-                Dimension + 1,
-                DimensionCount
-            >::apply(b_contained, b_containing, strategy, state);
-    }
-};
-
-template
-<
-    typename Box1,
-    typename Box2,
-    typename Strategy,
-    std::size_t DimensionCount
->
-struct box_in_box_helper<Box1, Box2, Strategy, DimensionCount, DimensionCount>
-{
-    static inline void apply(Box1 const& , Box2 const& , Strategy const&, within_state&)
-    {
-    }
-};
-
-template
-<
-    typename Box1,
-    typename Box2,
-    typename Strategy
->
-struct box_in_box
-{
-    static inline int apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
-    {
-        assert_dimension_equal<Box1, Box2>();
-        within_state state;
-        box_in_box_helper
-            <
-                Box1, Box2, Strategy,
-                0, dimension<Box1>::type::value
-            >::apply(box1, box2, strategy, state);
-        return state.code();
-    }
-};
-
-
 template
 <
     typename Point,
@@ -254,7 +60,7 @@
 >
 struct point_in_ring
 {
-    BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategy<Strategy>) );
+    BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal<Strategy>) );
 
     static inline int apply(Point const& point, Ring const& ring,
             Strategy const& strategy)
@@ -294,7 +100,6 @@
 };
 
 
-
 // Polygon: in exterior ring, and if so, not within interior ring(s)
 template
 <
@@ -306,7 +111,7 @@
 >
 struct point_in_polygon
 {
-    BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategy<Strategy>) );
+    BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal<Strategy>) );
 
     static inline int apply(Point const& point, Polygon const& poly,
             Strategy const& strategy)
@@ -378,137 +183,60 @@
 
 template <typename Point, typename Box, typename Strategy>
 struct within<point_tag, box_tag, Point, Box, Strategy>
-    : detail::within::point_in_box
-            <
-                Point,
-                Box,
-                Strategy
-            >
-{};
+{
+    static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
+    {
+        return strategy.apply(point, box);
+    }
+};
 
 template <typename Box1, typename Box2, typename Strategy>
 struct within<box_tag, box_tag, Box1, Box2, Strategy>
-    : detail::within::box_in_box
-            <
-                Box1,
-                Box2,
-                Strategy
-            >
-{};
+{
+    static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
+    {
+        assert_dimension_equal<Box1, Box2>();
+        return strategy.apply(box1, box2);
+    }
+};
 
 
 
 template <typename Point, typename Ring, typename Strategy>
 struct within<point_tag, ring_tag, Point, Ring, Strategy>
-    : detail::within::point_in_ring
-        <
-            Point,
-            Ring,
-            order_as_direction<geometry::point_order<Ring>::value>::value,
-            geometry::closure<Ring>::value,
-            Strategy
-        >
-{};
+{
+    static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
+    {
+        return detail::within::point_in_ring
+            <
+                Point,
+                Ring,
+                order_as_direction<geometry::point_order<Ring>::value>::value,
+                geometry::closure<Ring>::value,
+                Strategy
+            >::apply(point, ring, strategy) == 1;
+    }
+};
 
 template <typename Point, typename Polygon, typename Strategy>
 struct within<point_tag, polygon_tag, Point, Polygon, Strategy>
-    : detail::within::point_in_polygon
-        <
-            Point,
-            Polygon,
-            order_as_direction<geometry::point_order<Polygon>::value>::value,
-            geometry::closure<Polygon>::value,
-            Strategy
-        >
-{};
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-namespace strategy { namespace within
 {
-
-/// Strategy for box-in-box (not used but has to be present for default strategy)
-struct unused_strategy {};
-
-namespace services
-{
-
-// Specialize for box-in-areal (box-in-box). This is meant to do box-in-box
-// but will be catched by box-in-any-areal, which has to change later
-// (we might introduce another tag which is not "areal", derived by poly/ring/
-// multi_poly, but NOT by box, and use that here. E.g. "polygonal")
-// Using cartesian prevents spherical yet from compiling, which is good.
-template <typename Box1, typename Box2>
-struct default_strategy<box_tag, areal_tag, cartesian_tag, cartesian_tag, Box1, Box2>
-{
-    typedef unused_strategy type;
+    static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
+    {
+        return detail::within::point_in_polygon
+            <
+                Point,
+                Polygon,
+                order_as_direction<geometry::point_order<Polygon>::value>::value,
+                geometry::closure<Polygon>::value,
+                Strategy
+            >::apply(point, polygon, strategy) == 1;
+    }
 };
 
-} // namespace services
-
-}} // namespace strategy::within
-
-#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-
-
-namespace detail
-{
-
-template<typename Geometry1, typename Geometry2>
-inline int within_code(Geometry1 const& geometry1, Geometry2 const& geometry2)
-{
-    concept::check<Geometry1 const>();
-    concept::check<Geometry2 const>();
-
-    typedef typename point_type<Geometry1>::type point_type1;
-    typedef typename point_type<Geometry2>::type point_type2;
-
-    typedef typename strategy::within::services::default_strategy
-        <
-            typename tag<Geometry1>::type,
-            typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
-            typename cs_tag<point_type1>::type,
-            typename cs_tag<point_type2>::type,
-            point_type1,
-            point_type2
-        >::type strategy_type;
-
-    return dispatch::within
-        <
-            typename tag<Geometry1>::type,
-            typename tag<Geometry2>::type,
-            Geometry1,
-            Geometry2,
-            strategy_type
-        >::apply(geometry1, geometry2, strategy_type());
-}
-
-
-template<typename Geometry1, typename Geometry2, typename Strategy>
-inline int within_code(Geometry1 const& geometry1, Geometry2 const& geometry2,
-        Strategy const& strategy)
-{
-    // Always assume a point-in-polygon strategy here.
-    // Because for point-in-box, it makes no sense to specify one.
-    BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategy<Strategy>) );
-
-    concept::check<Geometry1 const>();
-    concept::check<Geometry2 const>();
-
-    return dispatch::within
-        <
-            typename tag<Geometry1>::type,
-            typename tag<Geometry2>::type,
-            Geometry1,
-            Geometry2,
-            Strategy
-        >::apply(geometry1, geometry2, strategy);
-}
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
 
-}
 
 /*!
 \brief \brief_check12{is completely inside}
@@ -538,7 +266,37 @@
 {
     concept::check<Geometry1 const>();
     concept::check<Geometry2 const>();
-    return detail::within_code(geometry1, geometry2) == 1;
+    assert_dimension_equal<Geometry1, Geometry2>();
+
+    typedef typename point_type<Geometry1>::type point_type1;
+    typedef typename point_type<Geometry2>::type point_type2;
+
+    typedef typename strategy::within::services::default_strategy
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            typename tag<Geometry1>::type,
+            typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+            typename tag_cast
+                <
+                    typename cs_tag<point_type1>::type, spherical_tag
+                >::type,
+            typename tag_cast
+                <
+                    typename cs_tag<point_type2>::type, spherical_tag
+                >::type,
+            Geometry1,
+            Geometry2
+        >::type strategy_type;
+
+    return dispatch::within
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            Geometry1,
+            Geometry2,
+            strategy_type
+        >::apply(geometry1, geometry2, strategy_type());
 }
 
 /*!
@@ -573,13 +331,25 @@
 inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2,
         Strategy const& strategy)
 {
-    // Always assume a point-in-polygon strategy here.
-    // Because for point-in-box, it makes no sense to specify one.
-    BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategy<Strategy>) );
-
+	concept::within::check
+        <
+            typename tag<Geometry1>::type, 
+            typename tag<Geometry2>::type, 
+            typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+            Strategy
+        >();
     concept::check<Geometry1 const>();
     concept::check<Geometry2 const>();
-    return detail::within_code(geometry1, geometry2, strategy) == 1;
+    assert_dimension_equal<Geometry1, Geometry2>();
+
+    return dispatch::within
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            Geometry1,
+            Geometry2,
+            Strategy
+        >::apply(geometry1, geometry2, strategy);
 }
 
 }} // namespace boost::geometry
Modified: trunk/boost/geometry/core/tags.hpp
==============================================================================
--- trunk/boost/geometry/core/tags.hpp	(original)
+++ trunk/boost/geometry/core/tags.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -20,18 +20,21 @@
 
 // Tags defining strategies linked to coordinate systems
 
+/// Tag used for casting spherical/geographic coordinate systems
+struct spherical_tag {};
+
 
 /// Tag indicating Cartesian coordinate system family (cartesian,epsg)
 struct cartesian_tag {};
 
 /// Tag indicating Spherical polar coordinate system family
-struct spherical_polar_tag {};
+struct spherical_polar_tag : spherical_tag {};
 
 /// Tag indicating Spherical equatorial coordinate system family
-struct spherical_equatorial_tag {};
+struct spherical_equatorial_tag : spherical_tag {};
 
 /// Tag indicating Geographic coordinate system family (geographic)
-struct geographic_tag {};
+struct geographic_tag : spherical_tag {};
 
 
 
@@ -53,6 +56,9 @@
 /// For areal types (polygon, multi_polygon, box, ring)
 struct areal_tag {};
 
+// Subset of areal types (polygon, multi_polygon, ring)
+struct polygonal_tag : areal_tag {}; 
+
 /// For volume types (also box (?), polyhedron)
 struct volumetric_tag {};
 
@@ -70,10 +76,10 @@
 struct linestring_tag : single_tag, linear_tag {};
 
 /// OGC Polygon identifying tag
-struct polygon_tag : single_tag, areal_tag {};
+struct polygon_tag : single_tag, polygonal_tag {};
 
 /// Convenience (linear) ring identifying tag
-struct ring_tag : single_tag, areal_tag {};
+struct ring_tag : single_tag, polygonal_tag {};
 
 /// Convenience 2D or 3D box (mbr / aabb) identifying tag
 struct box_tag : single_tag, areal_tag {};
Added: trunk/boost/geometry/multi/algorithms/covered_by.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/multi/algorithms/covered_by.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,68 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// 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_MULTI_ALGORITHMS_COVERED_BY_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP
+
+
+#include <boost/geometry/multi/core/closure.hpp>
+#include <boost/geometry/multi/core/point_order.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/algorithms/within.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Point, typename MultiPolygon, typename Strategy>
+struct covered_by<point_tag, multi_polygon_tag, Point, MultiPolygon, Strategy>
+{
+    static inline bool apply(Point const& point, 
+                MultiPolygon const& multi_polygon, Strategy const& strategy)
+    {
+        return detail::within::geometry_multi_within_code
+            <
+                Point,
+                MultiPolygon,
+                Strategy,
+                detail::within::point_in_polygon
+                        <
+                            Point,
+                            typename boost::range_value<MultiPolygon>::type,
+                            order_as_direction
+                                <
+                                    geometry::point_order<MultiPolygon>::value
+                                >::value,
+                            geometry::closure<MultiPolygon>::value,
+                            Strategy
+                        >
+            >::apply(point, multi_polygon, strategy) >= 0;
+    }
+};
+
+
+} // namespace dispatch
+
+
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP
Modified: trunk/boost/geometry/multi/algorithms/within.hpp
==============================================================================
--- trunk/boost/geometry/multi/algorithms/within.hpp	(original)
+++ trunk/boost/geometry/multi/algorithms/within.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -37,7 +37,7 @@
     typename Strategy,
     typename Policy
 >
-struct geometry_in_multi
+struct geometry_multi_within_code
 {
     static inline int apply(Geometry const& geometry,
             MultiGeometry const& multi,
@@ -48,7 +48,8 @@
             it != boost::end(multi);
             ++it)
         {
-            // Geometry within a multi: true if within one of them
+            // Geometry coding on multi: 1 (within) if within one of them;
+            // 0 (touch) if on border of one of them
             int const code = Policy::apply(geometry, *it, strategy);
             if (code != -1)
             {
@@ -70,21 +71,29 @@
 
 template <typename Point, typename MultiPolygon, typename Strategy>
 struct within<point_tag, multi_polygon_tag, Point, MultiPolygon, Strategy>
-    : detail::within::geometry_in_multi
-        <
-            Point,
-            MultiPolygon,
-            Strategy,
-            detail::within::point_in_polygon
-                    <
-                        Point,
-                        typename boost::range_value<MultiPolygon>::type,
-                        order_as_direction<geometry::point_order<MultiPolygon>::value>::value,
-                        geometry::closure<MultiPolygon>::value,
-                        Strategy
-                    >
-        >
-{};
+{
+    static inline bool apply(Point const& point, 
+                MultiPolygon const& multi_polygon, Strategy const& strategy)
+    {
+        return detail::within::geometry_multi_within_code
+            <
+                Point,
+                MultiPolygon,
+                Strategy,
+                detail::within::point_in_polygon
+                        <
+                            Point,
+                            typename boost::range_value<MultiPolygon>::type,
+                            order_as_direction
+                                <
+                                    geometry::point_order<MultiPolygon>::value
+                                >::value,
+                            geometry::closure<MultiPolygon>::value,
+                            Strategy
+                        >
+            >::apply(point, multi_polygon, strategy) == 1;
+    }
+};
 
 } // namespace dispatch
 #endif // DOXYGEN_NO_DISPATCH
Modified: trunk/boost/geometry/multi/core/tags.hpp
==============================================================================
--- trunk/boost/geometry/multi/core/tags.hpp	(original)
+++ trunk/boost/geometry/multi/core/tags.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -27,7 +27,7 @@
 struct multi_linestring_tag : multi_tag, linear_tag {};
 
 /// OGC Multi polygon identifying tag
-struct multi_polygon_tag : multi_tag, areal_tag {};
+struct multi_polygon_tag : multi_tag, polygonal_tag {};
 
 /// OGC Geometry Collection identifying tag
 struct geometry_collection_tag : multi_tag {};
Added: trunk/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,151 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// 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_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
+
+#include <boost/array.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy 
+{
+    
+namespace within
+{
+
+struct decide_within
+{
+    static inline bool apply(int side, bool& result)
+    {
+        if (side != 1)
+        {
+            result = false;
+            return false;
+        }
+        return true; // continue
+    }
+};
+
+struct decide_covered_by
+{
+    static inline bool apply(int side, bool& result)
+    {
+        if (side != 1)
+        {
+            result = side >= 0;
+            return false;
+        }
+        return true; // continue
+    }
+};
+
+
+template <typename Point, typename Box, typename Decide = decide_within>
+struct point_in_box_by_side
+{
+    typedef typename strategy::side::services::default_strategy
+    <
+        typename cs_tag<Box>::type
+    >::type side_strategy_type;
+
+    static inline bool apply(Point const& point, Box const& box)
+    {
+        // Create (counterclockwise) array of points, the fifth one closes it
+        // Every point should be on the LEFT side (=1), or ON the border (=0),
+        // So >= 1 or >= 0
+        boost::array<typename point_type<Box>::type, 5> bp;
+        geometry::detail::assign_box_corners_oriented<true>(box, bp);
+        bp[4] = bp[0];
+        
+        bool result = true;
+        side_strategy_type strategy;
+        boost::ignore_unused_variable_warning(strategy);
+        
+        for (int i = 1; i < 5; i++)
+        {
+            int const side = strategy.apply(point, bp[i - 1], bp[i]);
+            if (! Decide::apply(side, result))
+            {
+                return result;
+            }
+        }
+    
+        return result;
+    }
+};
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename Point, typename Box>
+struct default_strategy
+    <
+        point_tag, box_tag, 
+        point_tag, areal_tag, 
+        spherical_tag, spherical_tag, 
+        Point, Box
+    >
+{
+    typedef within::point_in_box_by_side
+                <
+					Point, Box, within::decide_within
+                > type;
+};
+
+
+
+}} // namespace within::services
+
+
+namespace covered_by { namespace services
+{
+
+
+template <typename Point, typename Box>
+struct default_strategy
+    <
+        point_tag, box_tag, 
+        point_tag, areal_tag, 
+        spherical_tag, spherical_tag, 
+        Point, Box
+    >
+{
+    typedef within::point_in_box_by_side
+                <
+                    Point, Box, within::decide_covered_by
+                > type;
+};
+
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
Modified: trunk/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp
==============================================================================
--- trunk/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp	(original)
+++ trunk/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -17,6 +17,7 @@
 #include <boost/geometry/util/select_calculation_type.hpp>
 
 #include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
 #include <boost/geometry/strategies/within.hpp>
 
 
@@ -181,23 +182,18 @@
 {
 
 // Register using "areal_tag" for ring, polygon, multi-polygon
-template <typename Point, typename PointOfSegment>
-struct default_strategy<point_tag, areal_tag, cartesian_tag, cartesian_tag, Point, PointOfSegment>
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, cartesian_tag, cartesian_tag, Point, Geometry>
 {
-    typedef winding<Point, PointOfSegment> type;
+    typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
 };
 
-template <typename Point, typename PointOfSegment>
-struct default_strategy<point_tag, areal_tag, spherical_polar_tag, spherical_polar_tag, Point, PointOfSegment>
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, spherical_tag, spherical_tag, Point, Geometry>
 {
-    typedef winding<Point, PointOfSegment> type;
+    typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
 };
 
-template <typename Point, typename PointOfSegment>
-struct default_strategy<point_tag, areal_tag, spherical_equatorial_tag, spherical_equatorial_tag, Point, PointOfSegment>
-{
-    typedef winding<Point, PointOfSegment> type;
-};
 
 } // namespace services
 
@@ -207,6 +203,29 @@
 }} // namespace strategy::within
 
 
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace strategy { namespace covered_by { namespace services
+{
+
+// Register using "areal_tag" for ring, polygon, multi-polygon
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, cartesian_tag, cartesian_tag, Point, Geometry>
+{
+    typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
+};
+
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, spherical_tag, spherical_tag, Point, Geometry>
+{
+    typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
+};
+
+
+}}} // namespace strategy::covered_by::services
+#endif
+
+
 }} // namespace boost::geometry
 
 
Added: trunk/boost/geometry/strategies/cartesian/box_in_box.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/strategies/cartesian/box_in_box.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,176 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// 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_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy 
+{
+    
+   
+namespace within
+{
+
+struct box_within_range
+{
+    template <typename BoxContainedValue, typename BoxContainingValue>
+    static inline bool apply(BoxContainedValue const& bed_min
+                , BoxContainedValue const& bed_max
+                , BoxContainingValue const& bing_min
+                , BoxContainingValue const& bing_max)
+    {
+        return bed_min > bing_min && bed_max < bing_max;
+    }
+};
+
+
+struct box_covered_by_range
+{
+    template <typename BoxContainedValue, typename BoxContainingValue>
+    static inline bool apply(BoxContainedValue const& bed_min
+                , BoxContainedValue const& bed_max
+                , BoxContainingValue const& bing_min
+                , BoxContainingValue const& bing_max)
+    {
+        return bed_min >= bing_min && bed_max <= bing_max;
+    }
+};
+
+
+template
+<
+    typename SubStrategy,
+    typename Box1,
+    typename Box2,
+    std::size_t Dimension,
+    std::size_t DimensionCount
+>
+struct relate_box_box_loop
+{
+    static inline bool apply(Box1 const& b_contained, Box2 const& b_containing)
+    {
+        assert_dimension_equal<Box1, Box2>();
+
+        if (! SubStrategy::apply(
+                    get<min_corner, Dimension>(b_contained), 
+                    get<max_corner, Dimension>(b_contained), 
+                    get<min_corner, Dimension>(b_containing), 
+                    get<max_corner, Dimension>(b_containing)
+                )
+            )
+        {
+            return false;
+        }
+
+        return relate_box_box_loop
+            <
+                SubStrategy,
+                Box1, Box2,
+                Dimension + 1, DimensionCount
+            >::apply(b_contained, b_containing);
+    }
+};
+
+template
+<
+    typename SubStrategy,
+    typename Box1,
+    typename Box2,
+    std::size_t DimensionCount
+>
+struct relate_box_box_loop<SubStrategy, Box1, Box2, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Box1 const& , Box2 const& )
+    {
+        return true;
+    }
+};
+
+template
+<
+    typename Box1,
+    typename Box2,
+    typename SubStrategy = box_within_range
+>
+struct box_in_box
+{
+    static inline bool apply(Box1 const& box1, Box2 const& box2)
+    {
+        return relate_box_box_loop
+            <
+                SubStrategy, 
+                Box1, Box2, 0, dimension<Box1>::type::value
+            >::apply(box1, box2);
+    }
+};
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename BoxContained, typename BoxContaining>
+struct default_strategy
+    <
+        box_tag, box_tag, 
+        box_tag, areal_tag, 
+        cartesian_tag, cartesian_tag, 
+        BoxContained, BoxContaining
+    >
+{
+    typedef within::box_in_box<BoxContained, BoxContaining> type;
+};
+
+
+}} // namespace within::services
+
+namespace covered_by { namespace services
+{
+
+template <typename BoxContained, typename BoxContaining>
+struct default_strategy
+    <
+        box_tag, box_tag, 
+        box_tag, areal_tag, 
+        cartesian_tag, cartesian_tag, 
+        BoxContained, BoxContaining
+    >
+{
+    typedef within::box_in_box
+                <
+					BoxContained, BoxContaining,
+                    within::box_covered_by_range
+                > type;
+};
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
Added: trunk/boost/geometry/strategies/cartesian/point_in_box.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/strategies/cartesian/point_in_box.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,172 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// 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_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy 
+{
+    
+namespace within
+{
+
+
+struct within_range
+{
+    template <typename Value1, typename Value2>
+    static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
+    {
+        return value > min_value && value < max_value;
+    }
+};
+
+
+struct covered_by_range
+{
+    template <typename Value1, typename Value2>
+    static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
+    {
+        return value >= min_value && value <= max_value;
+    }
+};
+
+
+template
+<
+    typename SubStrategy,
+    typename Point,
+    typename Box,
+    std::size_t Dimension,
+    std::size_t DimensionCount
+>
+struct relate_point_box_loop
+{
+    static inline bool apply(Point const& point, Box const& box)
+    {
+        if (! SubStrategy::apply(get<Dimension>(point), 
+				    get<min_corner, Dimension>(box), 
+                    get<max_corner, Dimension>(box))
+            )
+        {
+            return false;
+        }
+        
+        return relate_point_box_loop
+            <
+                SubStrategy,
+                Point, Box,
+                Dimension + 1, DimensionCount
+            >::apply(point, box);
+    }
+};
+
+
+template
+<
+    typename SubStrategy,
+    typename Point,
+    typename Box,
+    std::size_t DimensionCount
+>
+struct relate_point_box_loop<SubStrategy, Point, Box, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Point const& , Box const& )
+    {
+        return true;
+    }
+};
+
+
+template
+<
+    typename Point,
+    typename Box,
+    typename SubStrategy = within_range
+>
+struct point_in_box
+{
+    static inline bool apply(Point const& point, Box const& box)
+    {
+        return relate_point_box_loop
+            <
+                SubStrategy,
+                Point, Box, 
+                0, dimension<Point>::type::value
+            >::apply(point, box);
+    }
+};
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename Point, typename Box>
+struct default_strategy
+    <
+        point_tag, box_tag, 
+        point_tag, areal_tag, 
+        cartesian_tag, cartesian_tag, 
+        Point, Box
+    >
+{
+    typedef within::point_in_box<Point, Box> type; 
+};
+
+
+}} // namespace within::services
+
+
+namespace covered_by { namespace services
+{
+
+
+template <typename Point, typename Box>
+struct default_strategy
+    <
+        point_tag, box_tag, 
+        point_tag, areal_tag, 
+        cartesian_tag, cartesian_tag, 
+        Point, Box
+    >
+{
+    typedef within::point_in_box
+                <
+					Point, Box,
+                    within::covered_by_range
+                > type;
+};
+
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
Modified: trunk/boost/geometry/strategies/concepts/distance_concept.hpp
==============================================================================
--- trunk/boost/geometry/strategies/concepts/distance_concept.hpp	(original)
+++ trunk/boost/geometry/strategies/concepts/distance_concept.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -19,13 +19,7 @@
 
 #include <boost/concept_check.hpp>
 
-#include <boost/function_types/function_arity.hpp>
-#include <boost/function_types/is_member_function_pointer.hpp>
-#include <boost/function_types/parameter_types.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/int.hpp>
-#include <boost/mpl/plus.hpp>
-#include <boost/type_traits.hpp>
+#include <boost/geometry/util/parameter_type_of.hpp>
 
 #include <boost/geometry/geometries/concepts/point_concept.hpp>
 #include <boost/geometry/geometries/segment.hpp>
@@ -50,40 +44,15 @@
         template <typename ApplyMethod>
         static void apply(ApplyMethod const&)
         {
-            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_reference
+            typedef typename parameter_type_of
                 <
-                    typename boost::mpl::at
-                        <
-                            parameter_types,
-                            base_index
-                        >::type
+                    ApplyMethod, 0
                 >::type ptype1;
 
-            typedef typename boost::remove_reference
+            typedef typename parameter_type_of
                 <
-                    typename boost::mpl::at
-                        <
-                            parameter_types,
-                            typename boost::mpl::plus
-                                <
-                                    base_index,
-                                    boost::mpl::int_<1>
-                                >::type
-                        >::type
+                    ApplyMethod, 1
                 >::type ptype2;
 
             // 2) check if apply-arguments fulfill point concept
@@ -177,40 +146,14 @@
         template <typename ApplyMethod>
         static void apply(ApplyMethod const&)
         {
-            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_reference
+            typedef typename parameter_type_of
                 <
-                    typename boost::mpl::at
-                        <
-                            parameter_types,
-                            base_index
-                        >::type
+                    ApplyMethod, 0
                 >::type ptype;
 
-            typedef typename boost::remove_reference
+            typedef typename parameter_type_of
                 <
-                    typename boost::mpl::at
-                        <
-                            parameter_types,
-                            typename boost::mpl::plus
-                                <
-                                    base_index,
-                                    boost::mpl::int_<1>
-                                >::type
-                        >::type
+                    ApplyMethod, 1
                 >::type sptype;
 
             // 2) check if apply-arguments fulfill point concept
Modified: trunk/boost/geometry/strategies/concepts/within_concept.hpp
==============================================================================
--- trunk/boost/geometry/strategies/concepts/within_concept.hpp	(original)
+++ trunk/boost/geometry/strategies/concepts/within_concept.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -17,6 +17,9 @@
 
 
 #include <boost/concept_check.hpp>
+#include <boost/function_types/result_type.hpp>
+
+#include <boost/geometry/util/parameter_type_of.hpp>
 
 
 namespace boost { namespace geometry { namespace concept
@@ -24,57 +27,265 @@
 
 
 /*!
-    \brief Checks strategy for within (point-in-polygon)
-    \ingroup within
+\brief Checks strategy for within (point-in-polygon)
+\ingroup within
 */
 template <typename Strategy>
-class WithinStrategy
+class WithinStrategyPolygonal
 {
 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
 
-    // 1) must define state_type,
+    // 1) must define state_type
     typedef typename Strategy::state_type state_type;
 
-    // 2) must define point_type (of "point" in poly)
-    typedef typename Strategy::point_type point_type;
+    struct checker
+    {
+        template <typename ApplyMethod, typename ResultMethod>
+        static void apply(ApplyMethod const&, ResultMethod const& )
+        {
+            typedef typename parameter_type_of
+                <
+                    ApplyMethod, 0
+                >::type point_type;
+            typedef typename parameter_type_of
+                <
+                    ApplyMethod, 1
+                >::type segment_point_type;
+
+            // CHECK: apply-arguments should both fulfill point concept
+            BOOST_CONCEPT_ASSERT
+                (
+                    (concept::ConstPoint<point_type>)
+                );
+
+            BOOST_CONCEPT_ASSERT
+                (
+                    (concept::ConstPoint<segment_point_type>)
+                );
+
+            // CHECK: return types (result: int, apply: bool)
+            BOOST_MPL_ASSERT_MSG
+                (
+                    (boost::is_same
+                        <
+                            bool, typename boost::function_types::result_type<ApplyMethod>::type
+                        >::type::value),
+                    WRONG_RETURN_TYPE_OF_APPLY
+                    , (bool)
+                );
+            BOOST_MPL_ASSERT_MSG
+                (
+                    (boost::is_same
+                        <
+                            int, typename boost::function_types::result_type<ResultMethod>::type
+                        >::type::value),
+                    WRONG_RETURN_TYPE_OF_RESULT
+                    , (int)
+                );
+
+
+            // CHECK: calling method apply and result
+            Strategy const* str;
+            state_type* st;
+            point_type const* p;
+            segment_point_type const* sp;
+
+            bool b = str->apply(*p, *sp, *sp, *st);
+            int r = str->result(*st);
 
-    // 3) must define point_type, of polygon (segments)
-    typedef typename Strategy::segment_point_type spoint_type;
+            boost::ignore_unused_variable_warning(r);
+            boost::ignore_unused_variable_warning(b);
+            boost::ignore_unused_variable_warning(str);
+        }
+    };
+
+
+public :
+    BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
+    {
+        checker::apply(&Strategy::apply, &Strategy::result);
+    }
+#endif
+};
 
+template <typename Strategy>
+class WithinStrategyPointBox
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
 
-    struct check_methods
+    struct checker
     {
-        static void apply()
+        template <typename ApplyMethod>
+        static void apply(ApplyMethod const&)
         {
-            Strategy const* str;
+            typedef typename parameter_type_of
+                <
+                    ApplyMethod, 0
+                >::type point_type;
+            typedef typename parameter_type_of
+                <
+                    ApplyMethod, 1
+                >::type box_type;
+
+            // CHECK: apply-arguments should fulfill point/box concept
+            BOOST_CONCEPT_ASSERT
+                (
+                    (concept::ConstPoint<point_type>)
+                );
+
+            BOOST_CONCEPT_ASSERT
+                (
+                    (concept::ConstBox<box_type>)
+                );
+
+            // CHECK: return types (apply: bool)
+            BOOST_MPL_ASSERT_MSG
+                (
+                    (boost::is_same
+                        <
+                            bool, 
+                            typename boost::function_types::result_type<ApplyMethod>::type
+                        >::type::value),
+                    WRONG_RETURN_TYPE
+                    , (bool)
+                );
 
-            state_type* st;
+
+            // CHECK: calling method apply
+            Strategy const* str;
             point_type const* p;
-            spoint_type const* sp;
+            box_type const* bx;
 
-            // 4) must implement a method apply
-            //    having a point, two segment-points, and state
-            str->apply(*p, *sp, *sp, *st);
+            bool b = str->apply(*p, *bx);
 
-            // 5) must implement a method result returning int
-            int r = str->result(*st);
+            boost::ignore_unused_variable_warning(b);
+            boost::ignore_unused_variable_warning(str);
+        }
+    };
 
-            boost::ignore_unused_variable_warning(r);
+
+public :
+    BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
+    {
+        checker::apply(&Strategy::apply);
+    }
+#endif
+};
+
+template <typename Strategy>
+class WithinStrategyBoxBox
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+    struct checker
+    {
+        template <typename ApplyMethod>
+        static void apply(ApplyMethod const&)
+        {
+            typedef typename parameter_type_of
+                <
+                    ApplyMethod, 0
+                >::type box_type1;
+            typedef typename parameter_type_of
+                <
+                    ApplyMethod, 1
+                >::type box_type2;
+
+            // CHECK: apply-arguments should both fulfill box concept
+            BOOST_CONCEPT_ASSERT
+                (
+                    (concept::ConstBox<box_type1>)
+                );
+
+            BOOST_CONCEPT_ASSERT
+                (
+                    (concept::ConstBox<box_type2>)
+                );
+
+            // CHECK: return types (apply: bool)
+            BOOST_MPL_ASSERT_MSG
+                (
+                    (boost::is_same
+                        <
+                            bool, 
+                            typename boost::function_types::result_type<ApplyMethod>::type
+                        >::type::value),
+                    WRONG_RETURN_TYPE
+                    , (bool)
+                );
+
+
+            // CHECK: calling method apply
+            Strategy const* str;
+            box_type1 const* b1;
+            box_type2 const* b2;
+
+            bool b = str->apply(*b1, *b2);
+
+            boost::ignore_unused_variable_warning(b);
             boost::ignore_unused_variable_warning(str);
         }
     };
 
 
 public :
-    BOOST_CONCEPT_USAGE(WithinStrategy)
+    BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
     {
-        check_methods::apply();
+        checker::apply(&Strategy::apply);
     }
 #endif
 };
 
+// So now: boost::geometry::concept::within
+namespace within 
+{ 
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename FirstTag, typename SecondTag, typename CastedTag, typename Strategy>
+struct check_within
+{};
+
+
+template <typename AnyTag, typename Strategy>
+struct check_within<point_tag, AnyTag, areal_tag, Strategy>
+{
+    BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Strategy>) );
+};
+
+
+template <typename Strategy>
+struct check_within<point_tag, box_tag, areal_tag, Strategy>
+{
+    BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Strategy>) );
+};
+
+template <typename Strategy>
+struct check_within<box_tag, box_tag, areal_tag, Strategy>
+{
+    BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Strategy>) );
+};
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief Checks, in compile-time, the concept of any within-strategy
+\ingroup concepts
+*/
+template <typename FirstTag, typename SecondTag, typename CastedTag, typename Strategy>
+inline void check()
+{
+    dispatch::check_within<FirstTag, SecondTag, CastedTag, Strategy> c;
+    boost::ignore_unused_variable_warning(c);
+}
+
 
+}}}} // namespace boost::geometry::concept::within
 
-}}} // namespace boost::geometry::concept
 
 #endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
Added: trunk/boost/geometry/strategies/covered_by.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/strategies/covered_by.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,72 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// 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_STRATEGIES_COVERED_BY_HPP
+#define BOOST_GEOMETRY_STRATEGIES_COVERED_BY_HPP
+
+#include <boost/mpl/assert.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace covered_by
+{
+
+
+namespace services
+{
+
+/*!
+\brief Traits class binding a covered_by determination strategy to a coordinate system
+\ingroup covered_by
+\tparam TagContained tag (possibly casted) of point-type
+\tparam TagContained tag (possibly casted) of (possibly) containing type
+\tparam CsTagContained tag of coordinate system of point-type
+\tparam CsTagContaining tag of coordinate system of (possibly) containing type
+\tparam Geometry geometry-type of input (often point, or box)
+\tparam GeometryContaining geometry-type of input (possibly) containing type
+*/
+template
+<
+    typename TagContained,
+    typename TagContaining,
+    typename CastedTagContained,
+    typename CastedTagContaining,
+    typename CsTagContained,
+    typename CsTagContaining,
+    typename GeometryContained,
+    typename GeometryContaining
+>
+struct default_strategy
+{
+    BOOST_MPL_ASSERT_MSG
+        (
+            false, NOT_IMPLEMENTED_FOR_THIS_TYPES
+            , (types<GeometryContained, GeometryContaining>)
+        );
+};
+
+
+} // namespace services
+
+
+}} // namespace strategy::covered_by
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_COVERED_BY_HPP
+
Modified: trunk/boost/geometry/strategies/strategies.hpp
==============================================================================
--- trunk/boost/geometry/strategies/strategies.hpp	(original)
+++ trunk/boost/geometry/strategies/strategies.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -28,10 +28,12 @@
 #include <boost/geometry/strategies/within.hpp>
 
 #include <boost/geometry/strategies/cartesian/area_surveyor.hpp>
+#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
 #include <boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp>
 #include <boost/geometry/strategies/cartesian/centroid_weighted_length.hpp>
 #include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
 #include <boost/geometry/strategies/cartesian/distance_projected_point.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
 #include <boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp>
 #include <boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
 #include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
@@ -43,6 +45,7 @@
 #include <boost/geometry/strategies/spherical/ssf.hpp>
 
 #include <boost/geometry/strategies/agnostic/hull_graham_andrew.hpp>
+#include <boost/geometry/strategies/agnostic/point_in_box_by_side.hpp>
 #include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
 #include <boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp>
 
Modified: trunk/boost/geometry/strategies/within.hpp
==============================================================================
--- trunk/boost/geometry/strategies/within.hpp	(original)
+++ trunk/boost/geometry/strategies/within.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -16,7 +16,6 @@
 
 #include <boost/mpl/assert.hpp>
 
-#include <boost/geometry/strategies/tags.hpp>
 
 namespace boost { namespace geometry
 {
@@ -29,28 +28,32 @@
 {
 
 /*!
-    \brief Traits class binding a within determination strategy to a coordinate system
-    \ingroup within
-    \tparam CsTagContained tag of coordinate system of point-type
-    \tparam CsTagContained tag of coordinate system of segment-type
-    \tparam Point point-type of input points
-    \tparam PointContaining point-type of input segment-points
+\brief Traits class binding a within determination strategy to a coordinate system
+\ingroup within
+\tparam TagContained tag (possibly casted) of point-type
+\tparam TagContained tag (possibly casted) of (possibly) containing type
+\tparam CsTagContained tag of coordinate system of point-type
+\tparam CsTagContaining tag of coordinate system of (possibly) containing type
+\tparam Geometry geometry-type of input (often point, or box)
+\tparam GeometryContaining geometry-type of input (possibly) containing type
 */
 template
 <
     typename TagContained,
     typename TagContaining,
+    typename CastedTagContained,
+    typename CastedTagContaining,
     typename CsTagContained,
     typename CsTagContaining,
-    typename Point,
-    typename PointContaining
+    typename GeometryContained,
+    typename GeometryContaining
 >
 struct default_strategy
 {
     BOOST_MPL_ASSERT_MSG
         (
             false, NOT_IMPLEMENTED_FOR_THIS_TYPES
-            , (types<Point, PointContaining>)
+            , (types<GeometryContained, GeometryContaining>)
         );
 };
 
Added: trunk/boost/geometry/util/parameter_type_of.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/util/parameter_type_of.hpp	2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,75 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// 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_UTIL_PARAMETER_TYPE_OF_HPP
+#define BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP
+
+
+#include <boost/function_types/function_arity.hpp>
+#include <boost/function_types/is_member_function_pointer.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/plus.hpp>
+#include <boost/type_traits.hpp>
+
+
+namespace boost { namespace geometry
+{ 
+
+
+/*!
+\brief Meta-function selecting a parameter type of a (member) function, by index
+\ingroup utility
+ */
+template <typename Method, std::size_t Index>
+struct parameter_type_of
+{
+    typedef typename boost::function_types::parameter_types
+        <
+            Method
+        >::type parameter_types;
+
+    typedef typename boost::mpl::if_
+        <
+            boost::function_types::is_member_function_pointer<Method>,
+            boost::mpl::int_<1>,
+            boost::mpl::int_<0>
+        >::type base_index_type;
+        
+    typedef typename boost::mpl::if_c
+        <
+            Index == 0,
+            base_index_type,
+            typename boost::mpl::plus
+                <
+                    base_index_type,
+                    boost::mpl::int_<Index>
+                >::type
+        >::type indexed_type;
+
+    typedef typename boost::remove_reference
+        <
+            typename boost::mpl::at
+                <
+                    parameter_types,
+                    indexed_type
+                >::type
+        >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP