]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/geometry/algorithms/detail/is_valid/has_spikes.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / is_valid / has_spikes.hpp
index 96efec79cdb2844e6dc96ad5a4d2dc12072e4492..9f1091ffdbb8fa1b1945552df18cfb477268e4b8 100644 (file)
@@ -1,6 +1,6 @@
 // Boost.Geometry (aka GGL, Generic Geometry Library)
 
-// Copyright (c) 2014-2017, Oracle and/or its affiliates.
+// Copyright (c) 2014-2019, Oracle and/or its affiliates.
 
 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -28,7 +28,7 @@
 
 #include <boost/geometry/views/closeable_view.hpp>
 
-#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
 #include <boost/geometry/algorithms/validity_failure_type.hpp>
 #include <boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp>
 #include <boost/geometry/io/dsv/write.hpp>
@@ -42,7 +42,7 @@ namespace boost { namespace geometry
 namespace detail { namespace is_valid
 {
 
-template <typename Point>
+template <typename Point, typename Strategy>
 struct equal_to
 {
     Point const& m_point;
@@ -54,11 +54,11 @@ struct equal_to
     template <typename OtherPoint>
     inline bool operator()(OtherPoint const& other) const
     {
-        return geometry::equals(m_point, other);
+        return geometry::detail::equals::equals_point_point(m_point, other, Strategy());
     }
 };
 
-template <typename Point>
+template <typename Point, typename Strategy>
 struct not_equal_to
 {
     Point const& m_point;
@@ -70,7 +70,7 @@ struct not_equal_to
     template <typename OtherPoint>
     inline bool operator()(OtherPoint const& other) const
     {
-        return ! geometry::equals(other, m_point);
+        return ! geometry::detail::equals::equals_point_point(other, m_point, Strategy());
     }
 };
 
@@ -79,11 +79,16 @@ struct not_equal_to
 template <typename Range, closure_selector Closure>
 struct has_spikes
 {
-    template <typename Iterator>
+    template <typename Iterator, typename SideStrategy>
     static inline Iterator find_different_from_first(Iterator first,
-                                                     Iterator last)
+                                                     Iterator last,
+                                                     SideStrategy const& )
     {
-        typedef not_equal_to<typename point_type<Range>::type> not_equal;
+        typedef not_equal_to
+            <
+                typename point_type<Range>::type,
+                typename SideStrategy::equals_point_point_strategy_type
+            > not_equal;
 
         BOOST_GEOMETRY_ASSERT(first != last);
 
@@ -92,6 +97,37 @@ struct has_spikes
         return std::find_if(second, last, not_equal(*first));
     }
 
+    template <typename View, typename VisitPolicy, typename SideStrategy>
+    static inline bool apply_at_closure(View const& view, VisitPolicy& visitor,
+                                        SideStrategy const& strategy,
+                                        bool is_linear)
+    {
+        boost::ignore_unused(visitor);
+
+        typedef typename boost::range_iterator<View const>::type iterator;
+
+        iterator cur = boost::begin(view);
+        typename boost::range_reverse_iterator
+            <
+                View const
+            >::type prev = find_different_from_first(boost::rbegin(view),
+                                                     boost::rend(view),
+                                                     strategy);
+
+        iterator next = find_different_from_first(cur, boost::end(view),
+                                                  strategy);
+        if (detail::is_spike_or_equal(*next, *cur, *prev, strategy))
+        {
+            return
+                ! visitor.template apply<failure_spikes>(is_linear, *cur);
+        }
+        else
+        {
+            return ! visitor.template apply<no_failure>();
+        }
+    }
+
+
     template <typename VisitPolicy, typename SideStrategy>
     static inline bool apply(Range const& range, VisitPolicy& visitor,
                              SideStrategy const& strategy)
@@ -108,7 +144,7 @@ struct has_spikes
 
         iterator prev = boost::begin(view);
 
-        iterator cur = find_different_from_first(prev, boost::end(view));
+        iterator cur = find_different_from_first(prev, boost::end(view), strategy);
         if (cur == boost::end(view))
         {
             // the range has only one distinct point, so it
@@ -116,7 +152,7 @@ struct has_spikes
             return ! visitor.template apply<no_failure>();
         }
 
-        iterator next = find_different_from_first(cur, boost::end(view));
+        iterator next = find_different_from_first(cur, boost::end(view), strategy);
         if (next == boost::end(view))
         {
             // the range has only two distinct points, so it
@@ -126,36 +162,25 @@ struct has_spikes
 
         while (next != boost::end(view))
         {
-            if ( geometry::detail::point_is_spike_or_equal(*prev, *next, *cur,
-                                                           strategy) )
+            // Verify spike. TODO: this is a reverse order from expected
+            // in is_spike_or_equal, but this order calls the side
+            // strategy in the way to correctly detect the spikes,
+            // also in geographic cases going over the pole
+            if (detail::is_spike_or_equal(*next, *cur, *prev, strategy))
             {
                 return
                     ! visitor.template apply<failure_spikes>(is_linear, *cur);
             }
             prev = cur;
             cur = next;
-            next = find_different_from_first(cur, boost::end(view));
+            next = find_different_from_first(cur, boost::end(view), strategy);
         }
 
-        if (geometry::equals(range::front(view), range::back(view)))
+        if (geometry::detail::equals::
+                equals_point_point(range::front(view), range::back(view),
+                                   strategy.get_equals_point_point_strategy()))
         {
-            iterator cur = boost::begin(view);
-            typename boost::range_reverse_iterator
-                <
-                    view_type const
-                >::type prev = find_different_from_first(boost::rbegin(view),
-                                                         boost::rend(view));
-
-            iterator next = find_different_from_first(cur, boost::end(view));
-            if (detail::point_is_spike_or_equal(*prev, *next, *cur, strategy))
-            {
-                return
-                    ! visitor.template apply<failure_spikes>(is_linear, *cur);
-            }
-            else
-            {
-                return ! visitor.template apply<no_failure>();
-            }
+            return apply_at_closure(view, visitor, strategy, is_linear);
         }
 
         return ! visitor.template apply<no_failure>();