1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2014-2015, Oracle and/or its affiliates.
4 
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6 
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
9 
10 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_DUPLICATES_HPP
11 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_DUPLICATES_HPP
12 
13 #include <boost/core/ignore_unused.hpp>
14 #include <boost/range.hpp>
15 
16 #include <boost/geometry/core/closure.hpp>
17 
18 #include <boost/geometry/policies/compare.hpp>
19 #include <boost/geometry/policies/is_valid/default_policy.hpp>
20 
21 #include <boost/geometry/views/closeable_view.hpp>
22 #include <boost/geometry/algorithms/validity_failure_type.hpp>
23 
24 
25 namespace boost { namespace geometry
26 {
27 
28 
29 #ifndef DOXYGEN_NO_DETAIL
30 namespace detail { namespace is_valid
31 {
32 
33 template <typename Range, closure_selector Closure>
34 struct has_duplicates
35 {
36     template <typename VisitPolicy>
applyboost::geometry::detail::is_valid::has_duplicates37     static inline bool apply(Range const& range, VisitPolicy& visitor)
38     {
39         boost::ignore_unused(visitor);
40 
41         typedef typename closeable_view<Range const, Closure>::type view_type;
42         typedef typename boost::range_const_iterator
43             <
44                 view_type const
45             >::type const_iterator;
46 
47         view_type view(range);
48 
49         if ( boost::size(view) < 2 )
50         {
51             return ! visitor.template apply<no_failure>();
52         }
53 
54         geometry::equal_to<typename boost::range_value<Range>::type> equal;
55 
56         const_iterator it = boost::const_begin(view);
57         const_iterator next = it;
58         ++next;
59         for (; next != boost::const_end(view); ++it, ++next)
60         {
61             if ( equal(*it, *next) )
62             {
63                 return ! visitor.template apply<failure_duplicate_points>(*it);
64             }
65         }
66         return ! visitor.template apply<no_failure>();
67     }
68 };
69 
70 
71 
72 }} // namespace detail::is_valid
73 #endif // DOXYGEN_NO_DETAIL
74 
75 
76 }} // namespace boost::geometry
77 
78 
79 
80 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_DUPLICATES_HPP
81