• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2014-2018, Oracle and/or its affiliates.
4 
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7 
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
10 
11 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_INVALID_COORDINATE_HPP
12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_INVALID_COORDINATE_HPP
13 
14 #include <cstddef>
15 
16 #include <boost/type_traits/is_floating_point.hpp>
17 
18 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
19 #include <boost/geometry/algorithms/validity_failure_type.hpp>
20 
21 #include <boost/geometry/core/coordinate_type.hpp>
22 #include <boost/geometry/core/point_type.hpp>
23 
24 #include <boost/geometry/iterators/point_iterator.hpp>
25 
26 #include <boost/geometry/views/detail/indexed_point_view.hpp>
27 
28 #include <boost/geometry/util/has_non_finite_coordinate.hpp>
29 
30 namespace boost { namespace geometry
31 {
32 
33 #ifndef DOXYGEN_NO_DETAIL
34 namespace detail { namespace is_valid
35 {
36 
37 struct always_valid
38 {
39     template <typename Geometry, typename VisitPolicy>
applyboost::geometry::detail::is_valid::always_valid40     static inline bool apply(Geometry const&, VisitPolicy& visitor)
41     {
42         return ! visitor.template apply<no_failure>();
43     }
44 };
45 
46 struct point_has_invalid_coordinate
47 {
48     template <typename Point, typename VisitPolicy>
applyboost::geometry::detail::is_valid::point_has_invalid_coordinate49     static inline bool apply(Point const& point, VisitPolicy& visitor)
50     {
51         boost::ignore_unused(visitor);
52 
53         return
54             geometry::has_non_finite_coordinate(point)
55             ?
56             (! visitor.template apply<failure_invalid_coordinate>())
57             :
58             (! visitor.template apply<no_failure>());
59     }
60 
61     template <typename Point>
applyboost::geometry::detail::is_valid::point_has_invalid_coordinate62     static inline bool apply(Point const& point)
63     {
64         return geometry::has_non_finite_coordinate(point);
65     }
66 };
67 
68 struct indexed_has_invalid_coordinate
69 {
70     template <typename Geometry, typename VisitPolicy>
applyboost::geometry::detail::is_valid::indexed_has_invalid_coordinate71     static inline bool apply(Geometry const& geometry, VisitPolicy& visitor)
72     {
73         geometry::detail::indexed_point_view<Geometry const, 0> p0(geometry);
74         geometry::detail::indexed_point_view<Geometry const, 1> p1(geometry);
75 
76         return point_has_invalid_coordinate::apply(p0, visitor)
77             || point_has_invalid_coordinate::apply(p1, visitor);
78     }
79 };
80 
81 
82 struct range_has_invalid_coordinate
83 {
84     struct point_has_valid_coordinates
85     {
86         template <typename Point>
applyboost::geometry::detail::is_valid::range_has_invalid_coordinate::point_has_valid_coordinates87         static inline bool apply(Point const& point)
88         {
89             return ! point_has_invalid_coordinate::apply(point);
90         }
91     };
92 
93     template <typename Geometry, typename VisitPolicy>
applyboost::geometry::detail::is_valid::range_has_invalid_coordinate94     static inline bool apply(Geometry const& geometry, VisitPolicy& visitor)
95     {
96         boost::ignore_unused(visitor);
97 
98         bool const has_valid_coordinates = detail::check_iterator_range
99             <
100                 point_has_valid_coordinates,
101                 true // do not consider an empty range as problematic
102             >::apply(geometry::points_begin(geometry),
103                      geometry::points_end(geometry));
104 
105         return has_valid_coordinates
106             ?
107             (! visitor.template apply<no_failure>())
108             :
109             (! visitor.template apply<failure_invalid_coordinate>());
110     }
111 };
112 
113 
114 template
115 <
116     typename Geometry,
117     typename Tag = typename tag<Geometry>::type,
118     bool HasFloatingPointCoordinates = boost::is_floating_point
119         <
120             typename coordinate_type<Geometry>::type
121         >::value
122 >
123 struct has_invalid_coordinate
124     : range_has_invalid_coordinate
125 {};
126 
127 template <typename Geometry, typename Tag>
128 struct has_invalid_coordinate<Geometry, Tag, false>
129     : always_valid
130 {};
131 
132 template <typename Point>
133 struct has_invalid_coordinate<Point, point_tag, true>
134     : point_has_invalid_coordinate
135 {};
136 
137 template <typename Segment>
138 struct has_invalid_coordinate<Segment, segment_tag, true>
139     : indexed_has_invalid_coordinate
140 {};
141 
142 template <typename Box>
143 struct has_invalid_coordinate<Box, box_tag, true>
144     : indexed_has_invalid_coordinate
145 {};
146 
147 
148 }} // namespace detail::is_valid
149 #endif // DOXYGEN_NO_DETAIL
150 
151 }} // namespace boost::geometry
152 
153 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_INVALID_COORDINATE_HPP
154