1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. 4 5 // Use, modification and distribution is subject to the Boost Software License, 6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 #ifndef BOOST_GEOMETRY_POLICIES_COMPARE_HPP 10 #define BOOST_GEOMETRY_POLICIES_COMPARE_HPP 11 12 13 #include <cstddef> 14 15 #include <boost/geometry/strategies/compare.hpp> 16 #include <boost/geometry/util/math.hpp> 17 18 19 namespace boost { namespace geometry 20 { 21 22 23 #ifndef DOXYGEN_NO_DETAIL 24 namespace detail { namespace compare 25 { 26 27 28 template 29 < 30 int Direction, 31 typename Point, 32 typename Strategy, 33 std::size_t Dimension, 34 std::size_t DimensionCount 35 > 36 struct compare_loop 37 { 38 typedef typename strategy::compare::detail::select_strategy 39 < 40 Strategy, Direction, Point, Dimension 41 >::type compare_type; 42 43 typedef typename geometry::coordinate_type<Point>::type coordinate_type; 44 applyboost::geometry::detail::compare::compare_loop45 static inline bool apply(Point const& left, Point const& right) 46 { 47 coordinate_type const& cleft = geometry::get<Dimension>(left); 48 coordinate_type const& cright = geometry::get<Dimension>(right); 49 50 if (geometry::math::equals(cleft, cright)) 51 { 52 return compare_loop 53 < 54 Direction, Point, Strategy, 55 Dimension + 1, DimensionCount 56 >::apply(left, right); 57 } 58 else 59 { 60 compare_type compare; 61 return compare(cleft, cright); 62 } 63 } 64 }; 65 66 template 67 < 68 int Direction, 69 typename Point, 70 typename Strategy, 71 std::size_t DimensionCount 72 > 73 struct compare_loop<Direction, Point, Strategy, DimensionCount, DimensionCount> 74 { applyboost::geometry::detail::compare::compare_loop75 static inline bool apply(Point const&, Point const&) 76 { 77 // On coming here, points are equal. Return true if 78 // direction = 0 (equal), false if -1/1 (greater/less) 79 return Direction == 0; 80 } 81 }; 82 83 84 template <int Direction, typename Point, typename Strategy> 85 struct compare_in_all_dimensions 86 { operator ()boost::geometry::detail::compare::compare_in_all_dimensions87 inline bool operator()(Point const& left, Point const& right) const 88 { 89 return detail::compare::compare_loop 90 < 91 Direction, Point, Strategy, 92 0, geometry::dimension<Point>::type::value 93 >::apply(left, right); 94 } 95 }; 96 97 98 template <typename Point, typename Strategy, std::size_t Dimension> 99 class compare_in_one_dimension 100 { 101 Strategy compare; 102 103 public : operator ()(Point const & left,Point const & right) const104 inline bool operator()(Point const& left, Point const& right) const 105 { 106 typedef typename geometry::coordinate_type<Point>::type coordinate_type; 107 108 coordinate_type const& cleft = get<Dimension>(left); 109 coordinate_type const& cright = get<Dimension>(right); 110 return compare(cleft, cright); 111 } 112 }; 113 114 }} // namespace detail::compare 115 116 #endif 117 118 #ifndef DOXYGEN_NO_DISPATCH 119 namespace dispatch 120 { 121 122 template 123 < 124 int Direction, 125 typename Point, 126 typename Strategy, 127 int Dimension 128 > 129 struct compare_geometries 130 : detail::compare::compare_in_one_dimension 131 < 132 Point, 133 typename strategy::compare::detail::select_strategy 134 < 135 Strategy, Direction, Point, Dimension 136 >::type, 137 Dimension 138 > 139 {}; 140 141 142 // Specialization with -1: compare in all dimensions 143 template <int Direction, typename Point, typename Strategy> 144 struct compare_geometries<Direction, Point, Strategy, -1> 145 : detail::compare::compare_in_all_dimensions<Direction, Point, Strategy> 146 {}; 147 148 149 150 } // namespace dispatch 151 #endif // DOXYGEN_NO_DISPATCH 152 153 154 /*! 155 \brief Less functor, to sort points in ascending order. 156 \ingroup compare 157 \details This functor compares points and orders them on x, 158 then on y, then on z coordinate. 159 \tparam Geometry the geometry 160 \tparam Dimension the dimension to sort on, defaults to -1, 161 indicating ALL dimensions. That's to say, first on x, 162 on equal x-es then on y, etc. 163 If a dimension is specified, only that dimension is considered 164 \tparam Strategy underlying coordinate comparing functor, 165 defaults to the default comparison strategies 166 related to the point coordinate system. If specified, the specified 167 strategy is used. This can e.g. be std::less<double>. 168 */ 169 template 170 < 171 typename Point, 172 int Dimension = -1, 173 typename Strategy = strategy::compare::default_strategy 174 > 175 struct less 176 : dispatch::compare_geometries 177 < 178 1, // indicates ascending 179 Point, 180 Strategy, 181 Dimension 182 > 183 { 184 typedef Point first_argument_type; 185 typedef Point second_argument_type; 186 typedef bool result_type; 187 }; 188 189 190 /*! 191 \brief Greater functor 192 \ingroup compare 193 \details Can be used to sort points in reverse order 194 \see Less functor 195 */ 196 template 197 < 198 typename Point, 199 int Dimension = -1, 200 typename Strategy = strategy::compare::default_strategy 201 > 202 struct greater 203 : dispatch::compare_geometries 204 < 205 -1, // indicates descending 206 Point, 207 Strategy, 208 Dimension 209 > 210 {}; 211 212 213 /*! 214 \brief Equal To functor, to compare if points are equal 215 \ingroup compare 216 \tparam Geometry the geometry 217 \tparam Dimension the dimension to compare on, defaults to -1, 218 indicating ALL dimensions. 219 If a dimension is specified, only that dimension is considered 220 \tparam Strategy underlying coordinate comparing functor 221 */ 222 template 223 < 224 typename Point, 225 int Dimension = -1, 226 typename Strategy = strategy::compare::default_strategy 227 > 228 struct equal_to 229 : dispatch::compare_geometries 230 < 231 0, 232 Point, 233 Strategy, 234 Dimension 235 > 236 {}; 237 238 239 }} // namespace boost::geometry 240 241 242 #endif // BOOST_GEOMETRY_POLICIES_COMPARE_HPP 243