compare.hpp 5.7 KB

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