1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2014-2017, 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_BOX_HPP 12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_BOX_HPP 13 14 #include <cstddef> 15 16 #include <boost/core/ignore_unused.hpp> 17 18 #include <boost/geometry/core/access.hpp> 19 #include <boost/geometry/core/tags.hpp> 20 #include <boost/geometry/core/coordinate_dimension.hpp> 21 22 #include <boost/geometry/algorithms/validity_failure_type.hpp> 23 #include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp> 24 #include <boost/geometry/algorithms/dispatch/is_valid.hpp> 25 26 27 namespace boost { namespace geometry 28 { 29 30 31 #ifndef DOXYGEN_NO_DETAIL 32 namespace detail { namespace is_valid 33 { 34 35 template <typename Box, std::size_t I> 36 struct has_valid_corners 37 { 38 template <typename VisitPolicy> applyboost::geometry::detail::is_valid::has_valid_corners39 static inline bool apply(Box const& box, VisitPolicy& visitor) 40 { 41 if (math::equals(geometry::get<geometry::min_corner, I-1>(box), 42 geometry::get<geometry::max_corner, I-1>(box))) 43 { 44 return 45 visitor.template apply<failure_wrong_topological_dimension>(); 46 } 47 else if (geometry::get<geometry::min_corner, I-1>(box) 48 > 49 geometry::get<geometry::max_corner, I-1>(box)) 50 { 51 return visitor.template apply<failure_wrong_corner_order>(); 52 } 53 return has_valid_corners<Box, I-1>::apply(box, visitor); 54 } 55 }; 56 57 58 template <typename Box> 59 struct has_valid_corners<Box, 0> 60 { 61 template <typename VisitPolicy> applyboost::geometry::detail::is_valid::has_valid_corners62 static inline bool apply(Box const&, VisitPolicy& visitor) 63 { 64 boost::ignore_unused(visitor); 65 66 return visitor.template apply<no_failure>(); 67 } 68 }; 69 70 71 template <typename Box> 72 struct is_valid_box 73 { 74 template <typename VisitPolicy, typename Strategy> applyboost::geometry::detail::is_valid::is_valid_box75 static inline bool apply(Box const& box, VisitPolicy& visitor, Strategy const&) 76 { 77 return 78 ! has_invalid_coordinate<Box>::apply(box, visitor) 79 && 80 has_valid_corners<Box, dimension<Box>::value>::apply(box, visitor); 81 } 82 }; 83 84 }} // namespace detail::is_valid 85 #endif // DOXYGEN_NO_DETAIL 86 87 88 89 #ifndef DOXYGEN_NO_DISPATCH 90 namespace dispatch 91 { 92 93 94 // A box is always simple 95 // A box is a Polygon, and it satisfies the conditions for Polygon validity. 96 // 97 // The only thing we have to check is whether the max corner lies in 98 // the upper-right quadrant as defined by the min corner 99 // 100 // Reference (for polygon validity): OGC 06-103r4 (6.1.11.1) 101 template <typename Box> 102 struct is_valid<Box, box_tag> 103 : detail::is_valid::is_valid_box<Box> 104 {}; 105 106 107 } // namespace dispatch 108 #endif // DOXYGEN_NO_DISPATCH 109 110 111 112 }} // namespace boost::geometry 113 114 115 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_BOX_HPP 116