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