$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r76488 - in trunk: boost/geometry/algorithms boost/geometry/multi boost/geometry/strategies/agnostic libs/geometry/test/algorithms libs/geometry/test/multi/algorithms
From: barend.gehrels_at_[hidden]
Date: 2012-01-14 09:44:22
Author: barendgehrels
Date: 2012-01-14 09:44:21 EST (Sat, 14 Jan 2012)
New Revision: 76488
URL: http://svn.boost.org/trac/boost/changeset/76488
Log:
Fixed convex_hull for empty geometries by throwing exception
Text files modified: 
   trunk/boost/geometry/algorithms/convex_hull.hpp                 |    36 ++++++++++++++++++++++++++++++++++++    
   trunk/boost/geometry/multi/multi.hpp                            |     1 +                                       
   trunk/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp |     7 ++++++-                                 
   trunk/libs/geometry/test/algorithms/convex_hull.cpp             |     5 +++++                                   
   trunk/libs/geometry/test/algorithms/test_convex_hull.hpp        |    21 +++++++++++++++++++++                   
   trunk/libs/geometry/test/multi/algorithms/multi_convex_hull.cpp |     6 ++++++                                  
   6 files changed, 75 insertions(+), 1 deletions(-)
Modified: trunk/boost/geometry/algorithms/convex_hull.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/convex_hull.hpp	(original)
+++ trunk/boost/geometry/algorithms/convex_hull.hpp	2012-01-14 09:44:21 EST (Sat, 14 Jan 2012)
@@ -27,12 +27,41 @@
 
 #include <boost/geometry/views/detail/range_type.hpp>
 
+#include <boost/geometry/algorithms/num_points.hpp>
 #include <boost/geometry/algorithms/detail/as_range.hpp>
 
 
 namespace boost { namespace geometry
 {
 
+#if ! defined(BOOST_GEOMETRY_CONVEX_HULL_NO_THROW)
+
+/*!
+\brief Convex Hull Exception
+\ingroup convex_hull
+\details The convex_hull_exception is thrown if the free convex hull function is called with
+    geometries for which the hull cannot be calculated. For example: a linestring
+    without points, a polygon without points, an empty multi-geometry.
+\qbk{
+[heading See also]
+\* [link geometry.reference.algorithms.convex_hull the convex_hull function]
+}
+
+ */
+class convex_hull_exception : public geometry::exception
+{
+public:
+
+    inline convex_hull_exception() {}
+
+    virtual char const* what() const throw()
+    {
+        return "Boost.Geometry Convex Hull calculation exception";
+    }
+};
+
+#endif
+
 #ifndef DOXYGEN_NO_DETAIL
 namespace detail { namespace convex_hull
 {
@@ -143,6 +172,13 @@
 
     BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
 
+    if (geometry::num_points(geometry) == 0)
+    {
+#if ! defined(BOOST_GEOMETRY_CONVEX_HULL_NO_THROW)
+        throw convex_hull_exception();
+#endif
+        return;
+    }
 
     dispatch::convex_hull
         <
Modified: trunk/boost/geometry/multi/multi.hpp
==============================================================================
--- trunk/boost/geometry/multi/multi.hpp	(original)
+++ trunk/boost/geometry/multi/multi.hpp	2012-01-14 09:44:21 EST (Sat, 14 Jan 2012)
@@ -47,6 +47,7 @@
 #include <boost/geometry/multi/algorithms/unique.hpp>
 #include <boost/geometry/multi/algorithms/within.hpp>
 
+#include <boost/geometry/multi/algorithms/detail/for_each_range.hpp>
 #include <boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp>
 #include <boost/geometry/multi/algorithms/detail/multi_sum.hpp>
 
Modified: trunk/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
==============================================================================
--- trunk/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp	(original)
+++ trunk/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp	2012-01-14 09:44:21 EST (Sat, 14 Jan 2012)
@@ -67,12 +67,17 @@
     StrategyLess less;
     StrategyGreater greater;
 
-    get_extremes()
+    inline get_extremes()
         : first(true)
     {}
 
     inline void apply(InputRange const& range)
     {
+        if (boost::size(range) == 0)
+        {
+            return;
+        }
+
         // First iterate through this range
         // (this two-stage approach avoids many point copies,
         //  because iterators are kept in memory. Because iterators are
Modified: trunk/libs/geometry/test/algorithms/convex_hull.cpp
==============================================================================
--- trunk/libs/geometry/test/algorithms/convex_hull.cpp	(original)
+++ trunk/libs/geometry/test/algorithms/convex_hull.cpp	2012-01-14 09:44:21 EST (Sat, 14 Jan 2012)
@@ -45,8 +45,13 @@
                 12, 8, 5.245);
 
     // Waits for next cycle test_geometry<bg::model::box<P> >("box(0 0,2 2)", 5, 5, 4);
+
+    test_convex_hull_exception<bg::model::linestring<P> >();
+    test_convex_hull_exception<bg::model::polygon<P> >();
+    test_convex_hull_exception<bg::model::ring<P> >();
 }
 
+
 int test_main(int, char* [])
 {
     //test_all<bg::model::d2::point_xy<int> >();
Modified: trunk/libs/geometry/test/algorithms/test_convex_hull.hpp
==============================================================================
--- trunk/libs/geometry/test/algorithms/test_convex_hull.hpp	(original)
+++ trunk/libs/geometry/test/algorithms/test_convex_hull.hpp	2012-01-14 09:44:21 EST (Sat, 14 Jan 2012)
@@ -108,5 +108,26 @@
     test_geometry_order<Geometry, false>(wkt, size_original, size_hull, expected_area);
 }
 
+template <typename Geometry>
+void test_convex_hull_exception()
+{
+    Geometry geometry;
+    try
+    {
+        bg::model::polygon
+            <
+                typename bg::point_type<Geometry>::type
+            > hull;
+
+        bg::convex_hull(geometry, hull);
+    }
+    catch(bg::convex_hull_exception const& )
+    {
+        return;
+    }
+    BOOST_CHECK_MESSAGE(false, "A convex_hull_exception should have been thrown" );
+}
+
+
 
 #endif
Modified: trunk/libs/geometry/test/multi/algorithms/multi_convex_hull.cpp
==============================================================================
--- trunk/libs/geometry/test/multi/algorithms/multi_convex_hull.cpp	(original)
+++ trunk/libs/geometry/test/multi/algorithms/multi_convex_hull.cpp	2012-01-14 09:44:21 EST (Sat, 14 Jan 2012)
@@ -48,8 +48,14 @@
     typedef bg::model::multi_linestring<bg::model::linestring<P> > ml;
     typedef bg::model::multi_polygon<bg::model::polygon<P> > mpoly;
     test_geometry<mp>("multipoint((1.1 1.1), (2.5 2.1), (3.1 3.1), (4.9 1.1), (3.1 1.9))", 5, 4, 3.8);
+    // Ticket 6021:
+    test_geometry<mp>("multipoint((0 53), (0 103), (1 53))", 3, 4, 25);
     test_geometry<ml>("multilinestring((2 4, 3 4, 3 5), (4 3,4 4,5 4))", 6, 5, 3.0);
     test_geometry<mpoly>("multipolygon(((1 4,1 6,2 5,3 5,4 6,4 4,1 4)), ((4 2,4 3,6 3,6 2,4 2)))", 12, 7, 14.0);
+
+    test_convex_hull_exception<mp>();
+    test_convex_hull_exception<ml>();
+    test_convex_hull_exception<mpoly>();
 }