$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r68694 - in trunk/boost/geometry: algorithms algorithms/detail core extensions/gis/io/wkt geometries geometries/adapted/boost_polygon util
From: barend.gehrels_at_[hidden]
Date: 2011-02-07 13:45:12
Author: barendgehrels
Date: 2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
New Revision: 68694
URL: http://svn.boost.org/trac/boost/changeset/68694
Log:
Changed polygon concept to implement const/mutable usage
Therefore changed container_access
Added namespace "write" to enable writable containers or ranges
Reimplemented much of Boost.Polygon's polygon_with_hole_data adaption
Text files modified: 
   trunk/boost/geometry/algorithms/append.hpp                              |     2                                         
   trunk/boost/geometry/algorithms/area.hpp                                |     2                                         
   trunk/boost/geometry/algorithms/centroid.hpp                            |     2                                         
   trunk/boost/geometry/algorithms/clear.hpp                               |     6                                         
   trunk/boost/geometry/algorithms/detail/calculate_sum.hpp                |    17 ++                                      
   trunk/boost/geometry/core/container_access.hpp                          |    75 +++++++++++-                            
   trunk/boost/geometry/core/exterior_ring.hpp                             |    18 ++                                      
   trunk/boost/geometry/core/interior_rings.hpp                            |     2                                         
   trunk/boost/geometry/core/interior_type.hpp                             |    67 ++++++-----                             
   trunk/boost/geometry/core/ring_type.hpp                                 |    97 +++++++++--------                       
   trunk/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp                 |    30 ++++-                                   
   trunk/boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp |    29 +++-                                    
   trunk/boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp   |   112 ++++++++++++++++---                     
   trunk/boost/geometry/geometries/adapted/boost_polygon/polygon.hpp       |    31 +++-                                    
   trunk/boost/geometry/geometries/adapted/boost_polygon/ring.hpp          |    52 +++++++-                                
   trunk/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp    |   221 +++++++++++++++++++++++++++++++++++---- 
   trunk/boost/geometry/geometries/polygon.hpp                             |    60 ++++++++++                              
   trunk/boost/geometry/util/ensure_const_reference.hpp                    |     2                                         
   18 files changed, 636 insertions(+), 189 deletions(-)
Modified: trunk/boost/geometry/algorithms/append.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/append.hpp	(original)
+++ trunk/boost/geometry/algorithms/append.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -37,7 +37,7 @@
     {
         typename geometry::point_type<Geometry>::type copy;
         copy_coordinates(point, copy);
-        *(std::back_inserter(geometry)++) = copy;
+        write::push_back(geometry, copy);
     }
 };
 
Modified: trunk/boost/geometry/algorithms/area.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/area.hpp	(original)
+++ trunk/boost/geometry/algorithms/area.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -182,7 +182,7 @@
             Strategy,
             detail::area::ring_area
                 <
-                    typename ring_type<Polygon>::type,
+                    typename ring_type<Polygon const>::type,
                     order_as_direction<geometry::point_order<Polygon>::value>::value,
                     geometry::closure<Polygon>::value,
                     Strategy
Modified: trunk/boost/geometry/algorithms/centroid.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/centroid.hpp	(original)
+++ trunk/boost/geometry/algorithms/centroid.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -157,7 +157,7 @@
     else // if (n == 1)
     {
         // Take over the first point in a "coordinate neutral way"
-        copy_coordinates(range.front(), centroid);
+        copy_coordinates(*boost::begin(range), centroid);
         return false;
     }
     return true;
Modified: trunk/boost/geometry/algorithms/clear.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/clear.hpp	(original)
+++ trunk/boost/geometry/algorithms/clear.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -32,7 +32,7 @@
 {
     static inline void apply(Geometry& geometry)
     {
-        traits::clear<Geometry>::apply(geometry);
+        write::clear(geometry);
     }
 };
 
@@ -41,8 +41,8 @@
 {
     static inline void apply(Polygon& polygon)
     {
-        interior_rings(polygon).clear();
-        exterior_ring(polygon).clear();
+        write::clear(interior_rings(polygon));
+        write::clear(exterior_ring(polygon));
     }
 };
 
Modified: trunk/boost/geometry/algorithms/detail/calculate_sum.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/calculate_sum.hpp	(original)
+++ trunk/boost/geometry/algorithms/detail/calculate_sum.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -27,19 +27,26 @@
     typename Strategy,
     typename Policy
 >
-struct calculate_polygon_sum
+class calculate_polygon_sum
 {
-    static inline ReturnType apply(Polygon const& poly, Strategy const& strategy)
+    template <typename Rings>
+    static inline ReturnType sum_interior_rings(Rings const& rings, Strategy const& strategy)
     {
-        ReturnType sum = Policy::apply(exterior_ring(poly), strategy);
-
-        typename interior_return_type<Polygon const>::type rings = interior_rings(poly);
+        ReturnType sum = ReturnType();
         for (BOOST_AUTO(it, boost::begin(rings)); it != boost::end(rings); ++it)
         {
             sum += Policy::apply(*it, strategy);
         }
         return sum;
     }
+
+public :
+    static inline ReturnType apply(Polygon const& poly, Strategy const& strategy)
+    {
+        return Policy::apply(exterior_ring(poly), strategy)
+            + sum_interior_rings(bg::interior_rings(poly), strategy)
+            ;
+    }
 };
 
 
Modified: trunk/boost/geometry/core/container_access.hpp
==============================================================================
--- trunk/boost/geometry/core/container_access.hpp	(original)
+++ trunk/boost/geometry/core/container_access.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -28,20 +28,47 @@
 
 /*!
 \brief Traits class to clear a geometry
-\note Might be obsolete as well...
 \ingroup traits
-\par Geometries:
-    - linestring
-    - linear_ring
-\par Specializations should provide:
-    - apply
  */
-template <typename Geometry>
+template <typename Container>
 struct clear
 {
-    static inline void apply(Geometry& geometry)
+    static inline void apply(Container& container)
     {
-        geometry.clear();
+        // The default action: act as it it is a std:: container
+        container.clear();
+    }
+};
+
+
+/*!
+\brief Traits class to append a point to a container (ring, linestring, multi*)
+\ingroup traits
+ */
+template <typename Container>
+struct push_back
+{
+    static inline void apply(Container& container,
+        typename boost::range_value<Container>::type const& item)
+    {
+        // The default action: act as it it is a std:: container
+        container.push_back(item);
+    }
+};
+
+
+
+/*!
+\brief Traits class to append a point to a container (ring, linestring, multi*)
+\ingroup traits
+ */
+template <typename Container>
+struct resize
+{
+    static inline void apply(Container& container, std::size_t new_size)
+    {
+        // The default action: act as it it is a std:: container
+        container.resize(new_size);
     }
 };
 
@@ -50,6 +77,36 @@
 } // namespace traits
 
 
+namespace write
+{
+
+// Free functions to conveniently avoid complex metafunctions
+// (Mainly) or internal usage
+
+
+template <typename Container>
+inline void clear(Container& container)
+{
+    traits::clear<Container>::apply(container);
+}
+
+template <typename Container>
+inline void resize(Container& container, std::size_t new_size)
+{
+    traits::resize<Container>::apply(container, new_size);
+}
+
+template <typename Container>
+inline void push_back(Container& container, typename boost::range_value<Container>::type const& item)
+{
+    traits::push_back<Container>::apply(container, item);
+}
+
+
+}
+
+
 }} // namespace boost::geometry
 
+
 #endif // BOOST_GEOMETRY_CORE_CONTAINER_ACCESS_HPP
Modified: trunk/boost/geometry/core/exterior_ring.hpp
==============================================================================
--- trunk/boost/geometry/core/exterior_ring.hpp	(original)
+++ trunk/boost/geometry/core/exterior_ring.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -11,6 +11,7 @@
 #define BOOST_GEOMETRY_CORE_EXTERIOR_RING_HPP
 
 
+#include <boost/mpl/assert.hpp>
 #include <boost/type_traits/remove_const.hpp>
 
 
@@ -40,7 +41,13 @@
 */
 template <typename Polygon>
 struct exterior_ring
-{};
+{
+    BOOST_MPL_ASSERT_MSG
+        (
+            false, NOT_IMPLEMENTED_FOR_THIS_POLYGON_TYPE
+            , (types<Polygon>)
+        );
+};
 
 
 } // namespace traits
@@ -52,7 +59,14 @@
 
 
 template <typename Tag, typename Geometry>
-struct exterior_ring {};
+struct exterior_ring 
+{
+    BOOST_MPL_ASSERT_MSG
+        (
+            false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+            , (types<Geometry>)
+        );
+};
 
 
 template <typename Polygon>
Modified: trunk/boost/geometry/core/interior_rings.hpp
==============================================================================
--- trunk/boost/geometry/core/interior_rings.hpp	(original)
+++ trunk/boost/geometry/core/interior_rings.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -18,8 +18,6 @@
 #include <boost/geometry/core/tag.hpp>
 #include <boost/geometry/core/tags.hpp>
 #include <boost/geometry/core/interior_type.hpp>
-#include <boost/geometry/util/add_const_if_c.hpp>
-#include <boost/geometry/util/ensure_const_reference.hpp>
 
 namespace boost { namespace geometry
 {
Modified: trunk/boost/geometry/core/interior_type.hpp
==============================================================================
--- trunk/boost/geometry/core/interior_type.hpp	(original)
+++ trunk/boost/geometry/core/interior_type.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -16,7 +16,6 @@
 
 #include <boost/geometry/core/tag.hpp>
 #include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/util/ensure_const_reference.hpp>
 
 namespace boost { namespace geometry
 {
@@ -25,18 +24,28 @@
 {
 
 /*!
-    \brief Traits class indicating interior container type of a polygon
-    \details defines inner container type, so the container containing
-            the interior rings
-    \ingroup traits
-    \par Geometries:
-        - polygon
-    \par Specializations should provide:
-        - typedef X type ( e.g. std::vector<myring<P>> )
-    \tparam Geometry geometry
+\brief Traits class indicating interior container type of a polygon
+\details defines inner container type, so the container containing
+        the interior rings
+\ingroup traits
+\par Geometries:
+    - polygon
+\par Specializations should provide:
+    - typedef X type ( e.g. std::vector<myring<P>> )
+\tparam Geometry geometry
 */
 template <typename Geometry>
-struct interior_type
+struct interior_const_type
+{
+    BOOST_MPL_ASSERT_MSG
+        (
+            false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+            , (types<Geometry>)
+        );
+};
+
+template <typename Geometry>
+struct interior_mutable_type
 {
     BOOST_MPL_ASSERT_MSG
         (
@@ -57,7 +66,7 @@
 
 
 template <typename GeometryTag, typename Geometry>
-struct interior_type
+struct interior_return_type
 {
     BOOST_MPL_ASSERT_MSG
         (
@@ -68,20 +77,23 @@
 
 
 template <typename Polygon>
-struct interior_type<polygon_tag, Polygon>
+struct interior_return_type<polygon_tag, Polygon>
 {
-    typedef typename boost::remove_reference
+    typedef typename boost::remove_const<Polygon>::type nc_polygon_type;
+
+    typedef typename mpl::if_
         <
-            typename traits::interior_type
-                <
-                    typename boost::remove_const<Polygon>::type
-                >::type
-        > type;
+            boost::is_const<Polygon>,
+            typename traits::interior_const_type<nc_polygon_type>::type,
+            typename traits::interior_mutable_type<nc_polygon_type>::type
+        >::type type;
 };
 
 
+
+
 template <typename GeometryTag, typename Geometry>
-struct interior_return_type
+struct interior_type
 {
     BOOST_MPL_ASSERT_MSG
         (
@@ -92,12 +104,12 @@
 
 
 template <typename Polygon>
-struct interior_return_type<polygon_tag, Polygon>
+struct interior_type<polygon_tag, Polygon>
 {
-    typedef typename traits::interior_type
+    typedef typename boost::remove_reference
         <
-            typename boost::remove_const<Polygon>::type
-        >::type type;
+            typename interior_return_type<polygon_tag, Polygon>::type
+        > type;
 };
 
 
@@ -131,13 +143,6 @@
         <
             typename tag<Geometry>::type,
             Geometry
-        >::type ir_type;
-
-    typedef typename mpl::if_
-        <
-            boost::is_const<Geometry>,
-            typename ensure_const_reference<ir_type>::type,
-            ir_type
         >::type type;
 };
 
Modified: trunk/boost/geometry/core/ring_type.hpp
==============================================================================
--- trunk/boost/geometry/core/ring_type.hpp	(original)
+++ trunk/boost/geometry/core/ring_type.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -18,7 +18,6 @@
 
 #include <boost/geometry/core/tag.hpp>
 #include <boost/geometry/core/tags.hpp>
-#include <boost/geometry/util/ensure_const_reference.hpp>
 
 
 namespace boost { namespace geometry
@@ -29,16 +28,26 @@
 
 
 /*!
-    \brief Traits class to indicate ring-type  of a polygon's exterior ring/interior rings
-    \ingroup traits
-    \par Geometries:
-        - polygon
-    \par Specializations should provide:
-        - typedef XXX type ( e.g. linear_ring<P> )
-    \tparam Geometry geometry
+\brief Traits class to indicate ring-type  of a polygon's exterior ring/interior rings
+\ingroup traits
+\par Geometries:
+    - polygon
+\par Specializations should provide:
+    - typedef XXX type ( e.g. linear_ring<P> )
+\tparam Geometry geometry
 */
 template <typename Geometry>
-struct ring_type
+struct ring_const_type
+{
+    BOOST_MPL_ASSERT_MSG
+        (
+            false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+            , (types<Geometry>)
+        );
+};
+
+template <typename Geometry>
+struct ring_mutable_type
 {
     BOOST_MPL_ASSERT_MSG
         (
@@ -55,73 +64,75 @@
 namespace core_dispatch
 {
 
-
 template <typename GeometryTag, typename Geometry>
-struct ring_type
+struct ring_return_type
 {};
 
 
+template <typename LineString>
+struct ring_return_type<linestring_tag, LineString>
+{
+    typedef LineString& type;
+};
+
+
 template <typename Ring>
-struct ring_type<ring_tag, Ring>
+struct ring_return_type<ring_tag, Ring>
 {
-    typedef Ring type;
+    typedef Ring& type;
 };
 
 
 template <typename Polygon>
-struct ring_type<polygon_tag, Polygon>
+struct ring_return_type<polygon_tag, Polygon>
 {
-    typedef typename boost::remove_reference
+    typedef typename boost::remove_const<Polygon>::type nc_polygon_type;
+
+    typedef typename mpl::if_
         <
-            typename traits::ring_type
-                <
-                    typename boost::remove_const<Polygon>::type
-                >::type
+            boost::is_const<Polygon>,
+            typename traits::ring_const_type<nc_polygon_type>::type,
+            typename traits::ring_mutable_type<nc_polygon_type>::type
         >::type type;
 };
 
 
-
 template <typename GeometryTag, typename Geometry>
-struct ring_return_type
+struct ring_type
 {};
 
 
-template <typename LineString>
-struct ring_return_type<linestring_tag, LineString>
-{
-    typedef LineString& type;
-};
-
-
 template <typename Ring>
-struct ring_return_type<ring_tag, Ring>
+struct ring_type<ring_tag, Ring>
 {
-    typedef Ring& type;
+    typedef Ring type;
 };
 
 
 template <typename Polygon>
-struct ring_return_type<polygon_tag, Polygon>
+struct ring_type<polygon_tag, Polygon>
 {
-    typedef typename traits::ring_type
+    typedef typename boost::remove_reference
         <
-            typename boost::remove_const<Polygon>::type
+            typename ring_return_type<polygon_tag, Polygon>::type
         >::type type;
 };
 
 
+
+
+
 } // namespace core_dispatch
 #endif
 
 
 /*!
-    \brief Meta-function which defines ring type of (multi)polygon geometry
-    \details a polygon contains one exterior ring
-        and zero or more interior rings (holes).
-        This meta function retrieves the type of the rings
-    \note Exterior ring and interior rings must have the same ring-type.
-    \ingroup core
+\brief Meta-function which defines ring type of (multi)polygon geometry
+\details a polygon contains one exterior ring
+    and zero or more interior rings (holes).
+    This meta function retrieves the type of the rings
+\note Exterior ring and interior rings must have the same ring-type.
+\ingroup core
 */
 template <typename Geometry>
 struct ring_type
@@ -141,15 +152,7 @@
         <
             typename tag<Geometry>::type,
             Geometry
-        >::type rr_type;
-
-    typedef typename mpl::if_
-        <
-            boost::is_const<Geometry>,
-            typename ensure_const_reference<rr_type>::type,
-            rr_type
         >::type type;
-
 };
 
 
Modified: trunk/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp
==============================================================================
--- trunk/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp	(original)
+++ trunk/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -232,12 +232,17 @@
 };
 
 
+// Geometry might be a value-type or reference-type
 template <typename Geometry>
 struct container_appender
 {
-    typedef typename geometry::point_type<Geometry>::type point_type;
+    typedef typename geometry::point_type
+        <
+            typename boost::remove_reference<Geometry>::type
+        >::type point_type;
+
     static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
-        std::string const& wkt, Geometry& out)
+        std::string const& wkt, Geometry out)
     {
         handle_open_parenthesis(it, end, wkt);
 
@@ -318,12 +323,24 @@
 template <typename Polygon>
 struct polygon_parser
 {
-    typedef typename ring_type<Polygon>::type ring_type;
+    typedef typename ring_return_type<Polygon>::type ring_return_type;
+    typedef container_appender<ring_return_type> appender;
+
+    template <typename Rings>
+    static inline void apply_rings(
+                tokenizer::iterator& it, tokenizer::iterator end,
+                std::string const& wkt, Rings& rings, int n)
+    {
+        BOOST_AUTO(interior_it, boost::begin(rings));
+
+        interior_it += (n - 1);
+        appender::apply(it, end, wkt, *interior_it);
+    }
+
 
     static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
                 std::string const& wkt, Polygon& poly)
     {
-        typedef container_appender<ring_type> appender;
 
         handle_open_parenthesis(it, end, wkt);
 
@@ -339,9 +356,8 @@
             }
             else
             {
-                interior_rings(poly).resize(n);
-                appender::apply(it, end, wkt,
-                        interior_rings(poly).back());
+                write::resize(interior_rings(poly), n);
+                apply_rings(it, end, wkt, interior_rings(poly), n);
             }
 
             if (it != end && *it == ",")
Modified: trunk/boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp
==============================================================================
--- trunk/boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp	(original)
+++ trunk/boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -25,14 +25,14 @@
 {
 
 
-template <typename Polygon, typename Ring>
+template <typename Polygon, typename RingProxy>
 class hole_iterator
     : public ::boost::iterator_facade
         <
-            hole_iterator<Polygon, Ring>,
-            Ring, // value type
+            hole_iterator<Polygon, RingProxy>,
+            RingProxy, // value type
             boost::forward_traversal_tag,
-            Ring // reference type
+            RingProxy // reference type
         >
 {
 public :
@@ -41,8 +41,9 @@
             Polygon
         >::iterator_holes_type ith_type;
 
-    explicit inline hole_iterator(ith_type const it)
-        : m_base(it)
+    explicit inline hole_iterator(Polygon& polygon, ith_type const it)
+        : m_polygon(polygon)
+        , m_base(it)
     {
     }
 
@@ -51,21 +52,27 @@
 private:
     friend class boost::iterator_core_access;
 
-    // Return a ring_proxy by value
-    inline Ring dereference() const
+    inline RingProxy dereference() const
     {
-        return Ring(*this->m_base);
+        return RingProxy(m_polygon, this->m_base);
     }
 
     inline void increment() { ++m_base; }
     inline void decrement() { --m_base; }
-    inline void advance(difference_type n) { m_base += n; }
+    inline void advance(difference_type n) 
+    { 
+        for (int i = 0; i < n; i++)
+        {
+            ++m_base; 
+        }
+    }
 
-    inline bool equal(hole_iterator<Polygon, Ring> const& other) const
+    inline bool equal(hole_iterator<Polygon, RingProxy> const& other) const
     {
         return this->m_base == other.m_base;
     }
 
+    Polygon& m_polygon;
     ith_type m_base;
 };
 
Modified: trunk/boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp
==============================================================================
--- trunk/boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp	(original)
+++ trunk/boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -14,6 +14,9 @@
 
 #include <boost/polygon/polygon.hpp>
 
+#include <boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp>
+#include <boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp>
+
 
 namespace boost { namespace geometry
 {
@@ -22,62 +25,129 @@
 {
 
 
+// Polygon should implement the boost::polygon::polygon_with_holes_concept
+// Specify constness in the template parameter if necessary
 template<typename Polygon>
 struct holes_proxy
 {
-    typedef typename boost::polygon::polygon_traits<Polygon>::coordinate_type coordinate_type;
-    typedef boost::polygon::polygon_data<coordinate_type> Ring;
-    typedef hole_iterator<Polygon, Ring> iterator_type;
+    typedef ring_proxy
+        <
+            typename boost::mpl::if_
+                <
+                    typename boost::is_const<Polygon>,
+                    Polygon const,
+                    Polygon
+                >::type
+        > proxy_type;
+    typedef hole_iterator<Polygon, proxy_type> iterator_type;
+
+    inline holes_proxy(Polygon& p)
+        : polygon(p)
+    {}
 
+    void clear()
+    {
+        Polygon empty;
+        // Clear the holes
+        polygon.set_holes
+            (
+                boost::polygon::begin_holes(empty),
+                boost::polygon::end_holes(empty)
+            );
+    }
 
-    inline holes_proxy(Polygon const& p)
-        : first(iterator_type(boost::polygon::begin_holes(p)))
-        , second(iterator_type(boost::polygon::end_holes(p)))
+    void resize(std::size_t new_size)
     {
+        std::vector<boost::polygon::polygon_data<double> > temporary_copy
+            (
+                boost::polygon::begin_holes(polygon),
+                boost::polygon::end_holes(polygon)
+            );
+        temporary_copy.resize(new_size);
+        polygon.set_holes(temporary_copy.begin(), temporary_copy.end());
     }
 
-    iterator_type first, second;
+    Polygon& polygon;
 };
 
 
 // Support holes_proxy for Boost.Range ADP
+
+// Const versions
 template<typename Polygon>
-inline typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type 
-            range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon>& ring)
+inline typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type 
+            range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon const> const& proxy)
 {
-    return ring.first;
+    typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type 
+            begin(proxy.polygon, boost::polygon::begin_holes(proxy.polygon));
+    return begin;
 }
 
 template<typename Polygon>
-inline typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type 
-            range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon> const& ring)
+inline typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type 
+            range_end(boost::geometry::adapt::bp::holes_proxy<Polygon const> const& proxy)
 {
-    return ring.first;
+    typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type 
+            end(proxy.polygon, boost::polygon::end_holes(proxy.polygon));
+    return end;
 }
 
+// Mutable versions
 template<typename Polygon>
 inline typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type 
-            range_end(boost::geometry::adapt::bp::holes_proxy<Polygon>& ring)
+            range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon>& proxy)
 {
-    return ring.second;
+    typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type 
+            begin(proxy.polygon, boost::polygon::begin_holes(proxy.polygon));
+    return begin;
 }
 
 template<typename Polygon>
 inline typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type 
-            range_end(boost::geometry::adapt::bp::holes_proxy<Polygon> const& ring)
+            range_end(boost::geometry::adapt::bp::holes_proxy<Polygon>& proxy)
 {
-    return ring.second;
+    typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type 
+            end(proxy.polygon, boost::polygon::end_holes(proxy.polygon));
+    return end;
 }
 
 
-}}}}
+}}
+
+namespace traits
+{
+
+template <typename Polygon>
+struct clear<adapt::bp::holes_proxy<Polygon> >
+{
+    static inline void apply(adapt::bp::holes_proxy<Polygon>& proxy)
+    {
+        proxy.clear();
+    }
+};
+
+template <typename Polygon>
+struct resize<adapt::bp::holes_proxy<Polygon> >
+{
+    static inline void apply(adapt::bp::holes_proxy<Polygon>& proxy, std::size_t new_size)
+    {
+        proxy.resize(new_size);
+    }
+};
+
+
+
+} // namespace traits
+
+
+}}
 
 
 // Specialize holes_proxy for Boost.Range
 namespace boost
 {
     template<typename Polygon>
-    struct range_iterator<geometry::adapt::bp::holes_proxy<Polygon> >
+    struct range_mutable_iterator<geometry::adapt::bp::holes_proxy<Polygon> >
     {
         typedef typename geometry::adapt::bp::holes_proxy<Polygon>::iterator_type type;
     };
@@ -85,12 +155,10 @@
     template<typename Polygon>
     struct range_const_iterator<geometry::adapt::bp::holes_proxy<Polygon> >
     {
-        typedef typename geometry::adapt::bp::holes_proxy<Polygon>::iterator_type type;
+        typedef typename geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type type;
     };
 
-
 } // namespace boost
 
 
-
 #endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLES_PROXY_HPP
Modified: trunk/boost/geometry/geometries/adapted/boost_polygon/polygon.hpp
==============================================================================
--- trunk/boost/geometry/geometries/adapted/boost_polygon/polygon.hpp	(original)
+++ trunk/boost/geometry/geometries/adapted/boost_polygon/polygon.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -37,17 +37,26 @@
     typedef polygon_tag type;
 };
 
-
+template <typename CoordinateType>
+struct ring_const_type<boost::polygon::polygon_with_holes_data<CoordinateType> >
+{
+    typedef adapt::bp::ring_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> const> type;
+};
 
 template <typename CoordinateType>
-struct ring_type<boost::polygon::polygon_with_holes_data<CoordinateType> >
+struct ring_mutable_type<boost::polygon::polygon_with_holes_data<CoordinateType> >
 {
-    typedef adapt::bp::ring_proxy<boost::polygon::polygon_data<CoordinateType> > type;
+    typedef adapt::bp::ring_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> > type;
 };
 
+template <typename CoordinateType>
+struct interior_const_type<boost::polygon::polygon_with_holes_data<CoordinateType> >
+{
+    typedef adapt::bp::holes_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> const> type;
+};
 
 template <typename CoordinateType>
-struct interior_type<boost::polygon::polygon_with_holes_data<CoordinateType> >
+struct interior_mutable_type<boost::polygon::polygon_with_holes_data<CoordinateType> >
 {
     typedef adapt::bp::holes_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> > type;
 };
@@ -57,16 +66,17 @@
 struct exterior_ring<boost::polygon::polygon_with_holes_data<CoordinateType> >
 {
     typedef boost::polygon::polygon_with_holes_data<CoordinateType> polygon_type;
-    typedef adapt::bp::ring_proxy<boost::polygon::polygon_data<CoordinateType> > proxy;
+    typedef adapt::bp::ring_proxy<polygon_type> proxy;
+    typedef adapt::bp::ring_proxy<polygon_type const> const_proxy;
 
     static inline proxy get(polygon_type& p)
     {
-        return proxy(boost::polygon::begin_points(p), boost::polygon::end_points(p));
+        return proxy(p);
     }
 
-    static inline proxy get(polygon_type const& p)
+    static inline const_proxy get(polygon_type const& p)
     {
-        return proxy(boost::polygon::begin_points(p), boost::polygon::end_points(p));
+        return const_proxy(p);
     }
 };
 
@@ -75,15 +85,16 @@
 {
     typedef boost::polygon::polygon_with_holes_data<CoordinateType> polygon_type;
     typedef adapt::bp::holes_proxy<polygon_type> proxy;
+    typedef adapt::bp::holes_proxy<polygon_type const> const_proxy;
 
     static inline proxy get(polygon_type& p)
     {
         return proxy(p);
     }
 
-    static inline proxy get(polygon_type const& p)
+    static inline const_proxy get(polygon_type const& p)
     {
-        return proxy(p);
+        return const_proxy(p);
     }
 };
 
Modified: trunk/boost/geometry/geometries/adapted/boost_polygon/ring.hpp
==============================================================================
--- trunk/boost/geometry/geometries/adapted/boost_polygon/ring.hpp	(original)
+++ trunk/boost/geometry/geometries/adapted/boost_polygon/ring.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -21,34 +21,67 @@
 #include <boost/geometry/core/tags.hpp>
 
 
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
 namespace boost { namespace geometry
 {
 
-
-#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
 namespace traits
 {
 
-
 template <typename CoordinateType>
 struct tag<boost::polygon::polygon_data<CoordinateType> >
 {
     typedef ring_tag type;
 };
 
+template <typename CoordinateType>
+struct clear<boost::polygon::polygon_data<CoordinateType> >
+{
+    static inline void apply(boost::polygon::polygon_data<CoordinateType>& data)
+    {
+        // There is no "clear" function but we can assign
+        // a newly (and therefore empty) constructed polygon
+        boost::polygon::assign(data, boost::polygon::polygon_data<CoordinateType>());
+    }
+};
+
+template <typename CoordinateType>
+struct push_back<boost::polygon::polygon_data<CoordinateType> >
+{
+    typedef boost::polygon::point_data<CoordinateType> point_type;
+
+    static inline void apply(boost::polygon::polygon_data<CoordinateType>& data,
+         point_type const& point)
+    {
+        // Boost.Polygon's polygons are not appendable. So create a temporary vector,
+        // add a record and set it to the original. Of course: this is not efficient.
+        // But there seems no other way (without using a wrapper)
+        std::vector<point_type> temporary_vector
+            (
+                boost::polygon::begin_points(data), 
+                boost::polygon::end_points(data)
+            );
+        temporary_vector.push_back(point);
+        data.set(temporary_vector.begin(), temporary_vector.end());
+    }
+};
+
 
-} // namespace traits
-#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
 
 
+} // namespace traits
+
 }} // namespace boost::geometry
 
 
 // Adapt Boost.Polygon's polygon_data to Boost.Range
+// This just translates to
+// polygon_data.begin() and polygon_data.end()
 namespace boost
 {
     template<typename CoordinateType>
-    struct range_iterator<boost::polygon::polygon_data<CoordinateType> >
+    struct range_mutable_iterator<boost::polygon::polygon_data<CoordinateType> >
     {
         typedef typename boost::polygon::polygon_traits
             <
@@ -65,7 +98,6 @@
             >::iterator_type type;
     };
 
-    // RangeEx
     template<typename CoordinateType>
     struct range_size<boost::polygon::polygon_data<CoordinateType> >
     {
@@ -115,13 +147,15 @@
     return polygon.end();
 }
 
-// RangeEx
 template<typename CoordinateType>
-inline std::size_t range_size(polygon_data<CoordinateType> const& polygon)
+inline std::size_t range_calculate_size(polygon_data<CoordinateType> const& polygon)
 {
     return polygon.size();
 }
 
 }}
 
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
 #endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_HPP
Modified: trunk/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp
==============================================================================
--- trunk/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp	(original)
+++ trunk/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -23,62 +23,202 @@
 namespace adapt { namespace bp
 {
 
+namespace detail
+{
+
+template <bool Mutable>
+struct modify
+{};
+
+template <>
+struct modify<true>
+{
+    template <typename Ring, typename Point>
+    static inline void push_back(Ring& ring, Point const& point) 
+    { 
+        // Boost.Polygon's polygons are not appendable. So create a temporary vector,
+        // add a record and set it to the original. Of course: this is not efficient.
+        // But there seems no other way (without using a wrapper)
+        std::vector<Point> temporary_vector
+            (
+                boost::polygon::begin_points(ring), 
+                boost::polygon::end_points(ring)
+            );
+        temporary_vector.push_back(point);
+        //boost::polygon::set_points(ring, temporary_vector.begin(), temporary_vector.end());
+        ring.set(temporary_vector.begin(), temporary_vector.end());
+    }
+
+};
+
+template <>
+struct modify<false>
+{
+    template <typename Ring, typename Point>
+    static inline void push_back(Ring& ring, Point const& point) 
+    { 
+    }
+
+};
+
+
+}
+
 
-// Polygon should be a "polygon_data" here; NOT polygon_with_holes_data
+// Polygon should implement the boost::polygon::polygon_with_holes_concept
+// Specify constness in the template parameter if necessary
 template<typename Polygon>
-struct ring_proxy
+class ring_proxy
 {
+public :
     typedef typename boost::polygon::polygon_traits
         <
-            Polygon
+            typename boost::remove_const<Polygon>::type
         >::iterator_type iterator_type;
 
-    inline ring_proxy(Polygon const& p)
-        : first(boost::polygon::begin_points(p))
-        , second(boost::polygon::end_points(p))
-    {
+    typedef typename boost::polygon::polygon_with_holes_traits
+        <
+            typename boost::remove_const<Polygon>::type
+        >::iterator_holes_type hole_iterator_type;
+
+    static const bool is_mutable = !boost::is_const<Polygon>::type::value;
+
+    inline ring_proxy(Polygon& p)
+        : m_polygon(p)
+        , m_do_hole(false)
+    {}
+
+    // Constructor used from hole_iterator
+    inline ring_proxy(Polygon& p, hole_iterator_type hole_it)
+        : m_polygon(p)
+        , m_do_hole(true)
+        , m_hole_it(hole_it)
+    {}
+
+    iterator_type begin() const 
+    { 
+        return m_do_hole 
+            ? boost::polygon::begin_points(*m_hole_it)
+            : boost::polygon::begin_points(m_polygon)
+            ;
     }
 
-    inline ring_proxy(iterator_type begin, iterator_type end)
-        : first(begin)
-        , second(end)
-    {
+    iterator_type begin()  
+    { 
+        return m_do_hole 
+            ? boost::polygon::begin_points(*m_hole_it)
+            : boost::polygon::begin_points(m_polygon)
+            ;
+    }
+
+    iterator_type end() const 
+    { 
+        return m_do_hole 
+            ? boost::polygon::end_points(*m_hole_it)
+            : boost::polygon::end_points(m_polygon)
+            ;
+    }
+
+    iterator_type end()  
+    { 
+        return m_do_hole 
+            ? boost::polygon::end_points(*m_hole_it)
+            : boost::polygon::end_points(m_polygon)
+            ;
+    }
+
+    // Mutable
+    void clear()  
+    { 
+        Polygon p;
+        if (m_do_hole)
+        {
+            // Does NOT work see comment above
+        }
+        else
+        {
+            boost::polygon::set_points(m_polygon,
+                boost::polygon::begin_points(p), 
+                boost::polygon::end_points(p));
+        }
+    }
+
+    void resize(std::size_t new_size)  
+    { 
+        if (m_do_hole)
+        {
+            // Does NOT work see comment above
+        }
+        else
+        {
+            // TODO: implement this by resizing the container
+        }
+    }
+
+
+
+    template <typename Point>
+    void push_back(Point const& point) 
+    { 
+        if (m_do_hole)
+        {
+            //detail::modify<is_mutable>::push_back(*m_hole_it, point);
+            //std::cout << "HOLE: " << typeid(*m_hole_it).name() << std::endl;
+            //std::cout << "HOLE: " << typeid(m_hole_it).name() << std::endl;
+            //std::cout << "HOLE: " << typeid(hole_iterator_type).name() << std::endl;
+
+            // Note, ths does NOT work because hole_iterator_type is defined
+            // as a const_iterator by Boost.Polygon
+            
+        }
+        else
+        {
+            detail::modify<is_mutable>::push_back(m_polygon, point);
+        }
     }
 
-    iterator_type first, second;
+
+private :
+    Polygon& m_polygon;
+    bool m_do_hole;
+    hole_iterator_type m_hole_it;
 };
 
 
+
+
 // Support geometry::adapt::bp::ring_proxy for Boost.Range ADP
 template<typename Polygon>
 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
-            range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon>& ring)
+            range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy)
 {
-    return ring.first;
+    return proxy.begin();
 }
 
 template<typename Polygon>
-inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
-            range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon> const& ring)
+inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type
+            range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy)
 {
-    return ring.first;
+    return proxy.begin();
 }
 
 template<typename Polygon>
 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
-            range_end(boost::geometry::adapt::bp::ring_proxy<Polygon>& ring)
+            range_end(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy)
 {
-    return ring.second;
+    return proxy.end();
 }
 
 template<typename Polygon>
-inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
-            range_end(boost::geometry::adapt::bp::ring_proxy<Polygon> const& ring)
+inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type
+            range_end(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy)
 {
-    return ring.second;
+    return proxy.end();
 }
 
 
+
+
 }} // namespace adapt::bp
 
 
@@ -91,6 +231,37 @@
     typedef ring_tag type;
 };
 
+
+template <typename Polygon>
+struct clear<adapt::bp::ring_proxy<Polygon> >
+{
+    static inline void apply(adapt::bp::ring_proxy<Polygon>& proxy)
+    {
+        proxy.clear();
+    }
+};
+
+
+template <typename Polygon>
+struct resize<adapt::bp::ring_proxy<Polygon> >
+{
+    static inline void apply(adapt::bp::ring_proxy<Polygon>& proxy, std::size_t new_size)
+    {
+        proxy.resize(new_size);
+    }
+};
+
+template <typename Polygon>
+struct push_back<adapt::bp::ring_proxy<Polygon> >
+{
+    static inline void apply(adapt::bp::ring_proxy<Polygon>& proxy, 
+        typename boost::polygon::polygon_traits<Polygon>::point_type const& point)
+    {
+        proxy.push_back(point);
+    }
+};
+
+
 } // namespace traits
 
 }} // namespace boost::geometry
@@ -99,7 +270,7 @@
 namespace boost
 {
     template<typename Polygon>
-    struct range_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
+    struct range_mutable_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
     {
         typedef typename geometry::adapt::bp::ring_proxy<Polygon>::iterator_type type;
     };
@@ -107,12 +278,10 @@
     template<typename Polygon>
     struct range_const_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
     {
-        typedef typename geometry::adapt::bp::ring_proxy<Polygon>::iterator_type type;
+        typedef typename geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type type;
     };
 
-
 } // namespace boost
 
 
 #endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP
-
Modified: trunk/boost/geometry/geometries/polygon.hpp
==============================================================================
--- trunk/boost/geometry/geometries/polygon.hpp	(original)
+++ trunk/boost/geometry/geometries/polygon.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -129,7 +129,34 @@
     template<typename> class PointAlloc,
     template<typename> class RingAlloc
 >
-struct ring_type
+struct ring_const_type
+<
+    model::polygon
+        <
+            Point, ClockWise, Closed,
+            PointList, RingList, PointAlloc, RingAlloc
+        >
+>
+{
+    typedef typename model::polygon
+        <
+            Point, ClockWise, Closed,
+            PointList, RingList,
+            PointAlloc, RingAlloc
+        >::ring_type const& type;
+};
+
+
+template
+<
+    typename Point,
+    bool ClockWise, bool Closed,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct ring_mutable_type
 <
     model::polygon
         <
@@ -155,7 +182,35 @@
     template<typename> class PointAlloc,
     template<typename> class RingAlloc
 >
-struct interior_type
+struct interior_const_type
+<
+    model::polygon
+        <
+            Point, ClockWise, Closed,
+            PointList, RingList,
+            PointAlloc, RingAlloc
+        >
+>
+{
+    typedef typename model::polygon
+        <
+            Point, ClockWise, Closed,
+            PointList, RingList,
+            PointAlloc, RingAlloc
+        >::inner_container_type const& type;
+};
+
+
+template
+<
+    typename Point,
+    bool ClockWise, bool Closed,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct interior_mutable_type
 <
     model::polygon
         <
@@ -173,6 +228,7 @@
         >::inner_container_type& type;
 };
 
+
 template
 <
     typename Point,
Modified: trunk/boost/geometry/util/ensure_const_reference.hpp
==============================================================================
--- trunk/boost/geometry/util/ensure_const_reference.hpp	(original)
+++ trunk/boost/geometry/util/ensure_const_reference.hpp	2011-02-07 13:44:49 EST (Mon, 07 Feb 2011)
@@ -8,6 +8,7 @@
 #ifndef BOOST_GEOMETRY_UTIL_ENSURE_CONST_REFERENCE_HPP
 #define BOOST_GEOMETRY_UTIL_ENSURE_CONST_REFERENCE_HPP
 
+#ifdef OBSOLETE
 
 #include <boost/mpl/if.hpp>
 #include <boost/type_traits.hpp>
@@ -45,5 +46,6 @@
 
 }} // namespace boost::geometry
 
+#endif
 
 #endif // BOOST_GEOMETRY_UTIL_ENSURE_CONST_REFERENCE_HPP