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 // 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/core/coordinate_type.hpp> 19 #include <boost/geometry/core/point_type.hpp> 20 21 #include <boost/geometry/util/has_non_finite_coordinate.hpp> 22 23 #include <boost/geometry/iterators/point_iterator.hpp> 24 #include <boost/geometry/views/detail/indexed_point_view.hpp> 25 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp> 26 27 28 namespace boost { namespace geometry 29 { 30 31 #ifndef DOXYGEN_NO_DETAIL 32 namespace detail { namespace is_valid 33 { 34 35 struct always_valid 36 { 37 template <typename Geometry, typename VisitPolicy> applyboost::geometry::detail::is_valid::always_valid38 static inline bool apply(Geometry const&, VisitPolicy& visitor) 39 { 40 return ! visitor.template apply<no_failure>(); 41 } 42 }; 43 44 struct point_has_invalid_coordinate 45 { 46 template <typename Point, typename VisitPolicy> applyboost::geometry::detail::is_valid::point_has_invalid_coordinate47 static inline bool apply(Point const& point, VisitPolicy& visitor) 48 { 49 boost::ignore_unused(visitor); 50 51 return 52 geometry::has_non_finite_coordinate(point) 53 ? 54 (! visitor.template apply<failure_invalid_coordinate>()) 55 : 56 (! visitor.template apply<no_failure>()); 57 } 58 59 template <typename Point> applyboost::geometry::detail::is_valid::point_has_invalid_coordinate60 static inline bool apply(Point const& point) 61 { 62 return geometry::has_non_finite_coordinate(point); 63 } 64 }; 65 66 struct indexed_has_invalid_coordinate 67 { 68 template <typename Geometry, typename VisitPolicy> applyboost::geometry::detail::is_valid::indexed_has_invalid_coordinate69 static inline bool apply(Geometry const& geometry, VisitPolicy& visitor) 70 { 71 geometry::detail::indexed_point_view<Geometry const, 0> p0(geometry); 72 geometry::detail::indexed_point_view<Geometry const, 1> p1(geometry); 73 74 return point_has_invalid_coordinate::apply(p0, visitor) 75 || point_has_invalid_coordinate::apply(p1, visitor); 76 } 77 }; 78 79 80 struct range_has_invalid_coordinate 81 { 82 struct point_has_valid_coordinates 83 { 84 template <typename Point> applyboost::geometry::detail::is_valid::range_has_invalid_coordinate::point_has_valid_coordinates85 static inline bool apply(Point const& point) 86 { 87 return ! point_has_invalid_coordinate::apply(point); 88 } 89 }; 90 91 template <typename Geometry, typename VisitPolicy> applyboost::geometry::detail::is_valid::range_has_invalid_coordinate92 static inline bool apply(Geometry const& geometry, VisitPolicy& visitor) 93 { 94 boost::ignore_unused(visitor); 95 96 bool const has_valid_coordinates = detail::check_iterator_range 97 < 98 point_has_valid_coordinates, 99 true // do not consider an empty range as problematic 100 >::apply(geometry::points_begin(geometry), 101 geometry::points_end(geometry)); 102 103 return has_valid_coordinates 104 ? 105 (! visitor.template apply<no_failure>()) 106 : 107 (! visitor.template apply<failure_invalid_coordinate>()); 108 } 109 }; 110 111 112 template 113 < 114 typename Geometry, 115 typename Tag = typename tag<Geometry>::type, 116 bool HasFloatingPointCoordinates = boost::is_floating_point 117 < 118 typename coordinate_type<Geometry>::type 119 >::value 120 > 121 struct has_invalid_coordinate 122 : range_has_invalid_coordinate 123 {}; 124 125 template <typename Geometry, typename Tag> 126 struct has_invalid_coordinate<Geometry, Tag, false> 127 : always_valid 128 {}; 129 130 template <typename Point> 131 struct has_invalid_coordinate<Point, point_tag, true> 132 : point_has_invalid_coordinate 133 {}; 134 135 template <typename Segment> 136 struct has_invalid_coordinate<Segment, segment_tag, true> 137 : indexed_has_invalid_coordinate 138 {}; 139 140 template <typename Box> 141 struct has_invalid_coordinate<Box, box_tag, true> 142 : indexed_has_invalid_coordinate 143 {}; 144 145 146 }} // namespace detail::is_valid 147 #endif // DOXYGEN_NO_DETAIL 148 149 }} // namespace boost::geometry 150 151 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_INVALID_COORDINATE_HPP 152