compare.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2017-2023.
  4. // Modifications copyright (c) 2017-2023, Oracle and/or its affiliates.
  5. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  6. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_GEOMETRY_POLICIES_COMPARE_HPP
  11. #define BOOST_GEOMETRY_POLICIES_COMPARE_HPP
  12. #include <cstddef>
  13. #include <boost/geometry/strategies/compare.hpp>
  14. #include <boost/geometry/strategies/spherical/compare.hpp>
  15. #include <boost/geometry/util/math.hpp>
  16. namespace boost { namespace geometry
  17. {
  18. /*!
  19. \brief Less functor, to sort points in ascending order.
  20. \ingroup compare
  21. \details This functor compares points and orders them on x,
  22. then on y, then on z coordinate.
  23. \tparam Point the geometry
  24. \tparam Dimension the dimension to sort on, defaults to -1,
  25. indicating ALL dimensions. That's to say, first on x,
  26. on equal x-es then on y, etc.
  27. If a dimension is specified, only that dimension is considered
  28. */
  29. template
  30. <
  31. typename Point = void,
  32. int Dimension = -1,
  33. typename StrategyOrTag = void
  34. >
  35. struct less_exact
  36. {
  37. using first_argument_type = Point;
  38. using second_argument_type = Point;
  39. using result_type = bool;
  40. inline bool operator()(Point const& left, Point const& right) const
  41. {
  42. return StrategyOrTag::template compare_type
  43. <
  44. strategy::compare::less,
  45. strategy::compare::equals_exact
  46. >::apply(left, right);
  47. }
  48. };
  49. template
  50. <
  51. typename Point = void,
  52. int Dimension = -1,
  53. typename StrategyOrTag = void
  54. >
  55. struct less
  56. {
  57. using first_argument_type = Point;
  58. using second_argument_type = Point;
  59. using result_type = bool;
  60. inline bool operator()(Point const& left, Point const& right) const
  61. {
  62. return StrategyOrTag::template compare_type
  63. <
  64. strategy::compare::less,
  65. strategy::compare::equals_epsilon
  66. >::apply(left, right);
  67. }
  68. };
  69. template <typename Point, int Dimension>
  70. struct less<Point, Dimension, void>
  71. {
  72. using first_argument_type = Point;
  73. using second_argument_type = Point;
  74. using result_type = bool;
  75. inline bool operator()(Point const& left, Point const& right) const
  76. {
  77. using strategy_type = typename strategy::compare::services::default_strategy
  78. <
  79. strategy::compare::less,
  80. strategy::compare::equals_epsilon,
  81. Point, Point,
  82. Dimension
  83. >::type;
  84. return strategy_type::apply(left, right);
  85. }
  86. };
  87. template <int Dimension, typename Strategy>
  88. struct less<void, Dimension, Strategy>
  89. {
  90. using result_type = bool;
  91. template <typename Point1, typename Point2>
  92. inline bool operator()(Point1 const& left, Point2 const& right) const
  93. {
  94. return Strategy::template compare_type
  95. <
  96. strategy::compare::less,
  97. strategy::compare::equals_epsilon
  98. >::apply(left, right);
  99. }
  100. };
  101. // for backward compatibility
  102. template <typename Point, int Dimension>
  103. struct less<Point, Dimension, boost::geometry::cartesian_tag>
  104. {
  105. using first_argument_type = Point;
  106. using second_argument_type = Point;
  107. using result_type = bool;
  108. inline bool operator()(Point const& left, Point const& right) const
  109. {
  110. using strategy_type = typename strategy::compare::services::default_strategy
  111. <
  112. strategy::compare::less,
  113. strategy::compare::equals_epsilon,
  114. Point, Point,
  115. Dimension,
  116. boost::geometry::cartesian_tag, boost::geometry::cartesian_tag
  117. >::type;
  118. return strategy_type::apply(left, right);
  119. }
  120. };
  121. template <typename Point, int Dimension>
  122. struct less<Point, Dimension, boost::geometry::spherical_tag>
  123. {
  124. using first_argument_type = Point;
  125. using second_argument_type = Point;
  126. using result_type = bool;
  127. inline bool operator()(Point const& left, Point const& right) const
  128. {
  129. using strategy_type = typename strategy::compare::services::default_strategy
  130. <
  131. strategy::compare::less,
  132. strategy::compare::equals_epsilon,
  133. Point, Point,
  134. Dimension,
  135. boost::geometry::spherical_tag, boost::geometry::spherical_tag
  136. >::type;
  137. return strategy_type::apply(left, right);
  138. }
  139. };
  140. template <typename Point, int Dimension>
  141. struct less<Point, Dimension, boost::geometry::geographic_tag>
  142. {
  143. using first_argument_type = Point;
  144. using second_argument_type = Point;
  145. using result_type = bool;
  146. inline bool operator()(Point const& left, Point const& right) const
  147. {
  148. using strategy_type = typename strategy::compare::services::default_strategy
  149. <
  150. strategy::compare::less,
  151. strategy::compare::equals_epsilon,
  152. Point, Point,
  153. Dimension,
  154. boost::geometry::geographic_tag, boost::geometry::geographic_tag
  155. >::type;
  156. return strategy_type::apply(left, right);
  157. }
  158. };
  159. template <int Dimension>
  160. struct less<void, Dimension, boost::geometry::cartesian_tag>
  161. {
  162. using result_type = bool;
  163. template <typename Point1, typename Point2>
  164. inline bool operator()(Point1 const& left, Point2 const& right) const
  165. {
  166. using strategy_type = typename strategy::compare::services::default_strategy
  167. <
  168. strategy::compare::less,
  169. strategy::compare::equals_epsilon,
  170. Point1, Point2,
  171. Dimension,
  172. boost::geometry::cartesian_tag, boost::geometry::cartesian_tag
  173. >::type;
  174. return strategy_type::apply(left, right);
  175. }
  176. };
  177. template <int Dimension>
  178. struct less<void, Dimension, boost::geometry::spherical_tag>
  179. {
  180. using result_type = bool;
  181. template <typename Point1, typename Point2>
  182. inline bool operator()(Point1 const& left, Point2 const& right) const
  183. {
  184. using strategy_type = typename strategy::compare::services::default_strategy
  185. <
  186. strategy::compare::less,
  187. strategy::compare::equals_epsilon,
  188. Point1, Point2,
  189. Dimension,
  190. boost::geometry::spherical_tag, boost::geometry::spherical_tag
  191. >::type;
  192. return strategy_type::apply(left, right);
  193. }
  194. };
  195. template <int Dimension>
  196. struct less<void, Dimension, boost::geometry::geographic_tag>
  197. {
  198. using result_type = bool;
  199. template <typename Point1, typename Point2>
  200. inline bool operator()(Point1 const& left, Point2 const& right) const
  201. {
  202. using strategy_type = typename strategy::compare::services::default_strategy
  203. <
  204. strategy::compare::less,
  205. strategy::compare::equals_epsilon,
  206. Point1, Point2,
  207. Dimension,
  208. boost::geometry::geographic_tag, boost::geometry::geographic_tag
  209. >::type;
  210. return strategy_type::apply(left, right);
  211. }
  212. };
  213. template <int Dimension>
  214. struct less<void, Dimension, void>
  215. {
  216. using result_type = bool;
  217. template <typename Point1, typename Point2>
  218. inline bool operator()(Point1 const& left, Point2 const& right) const
  219. {
  220. using strategy_type = typename strategy::compare::services::default_strategy
  221. <
  222. strategy::compare::less,
  223. strategy::compare::equals_epsilon,
  224. Point1, Point2,
  225. Dimension
  226. >::type;
  227. return strategy_type::apply(left, right);
  228. }
  229. };
  230. /*!
  231. \brief Greater functor
  232. \ingroup compare
  233. \details Can be used to sort points in reverse order
  234. \see Less functor
  235. */
  236. template
  237. <
  238. typename Point = void,
  239. int Dimension = -1,
  240. typename CSTag = void
  241. >
  242. struct greater
  243. {
  244. using first_argument_type = Point;
  245. using second_argument_type = Point;
  246. using result_type = bool;
  247. bool operator()(Point const& left, Point const& right) const
  248. {
  249. using strategy_type = typename strategy::compare::services::default_strategy
  250. <
  251. strategy::compare::greater,
  252. strategy::compare::equals_epsilon,
  253. Point, Point,
  254. Dimension,
  255. CSTag, CSTag
  256. >::type;
  257. return strategy_type::apply(left, right);
  258. }
  259. };
  260. template <int Dimension, typename CSTag>
  261. struct greater<void, Dimension, CSTag>
  262. {
  263. using result_type = bool;
  264. template <typename Point1, typename Point2>
  265. bool operator()(Point1 const& left, Point2 const& right) const
  266. {
  267. using strategy_type = typename strategy::compare::services::default_strategy
  268. <
  269. strategy::compare::greater,
  270. strategy::compare::equals_epsilon,
  271. Point1, Point2,
  272. Dimension,
  273. CSTag, CSTag
  274. >::type;
  275. return strategy_type::apply(left, right);
  276. }
  277. };
  278. template <typename Point, int Dimension>
  279. struct greater<Point, Dimension, void>
  280. {
  281. using first_argument_type = Point;
  282. using second_argument_type = Point;
  283. using result_type = bool;
  284. bool operator()(Point const& left, Point const& right) const
  285. {
  286. using strategy_type = typename strategy::compare::services::default_strategy
  287. <
  288. strategy::compare::greater,
  289. strategy::compare::equals_epsilon,
  290. Point, Point,
  291. Dimension
  292. >::type;
  293. return strategy_type::apply(left, right);
  294. }
  295. };
  296. template <int Dimension>
  297. struct greater<void, Dimension, void>
  298. {
  299. using result_type = bool;
  300. template <typename Point1, typename Point2>
  301. bool operator()(Point1 const& left, Point2 const& right) const
  302. {
  303. using strategy_type = typename strategy::compare::services::default_strategy
  304. <
  305. strategy::compare::greater,
  306. strategy::compare::equals_epsilon,
  307. Point1, Point2,
  308. Dimension
  309. >::type;
  310. return strategy_type::apply(left, right);
  311. }
  312. };
  313. /*!
  314. \brief Equal To functor, to compare if points are equal
  315. \ingroup compare
  316. \tparam Geometry the geometry
  317. \tparam Dimension the dimension to compare on, defaults to -1,
  318. indicating ALL dimensions.
  319. If a dimension is specified, only that dimension is considered
  320. */
  321. template
  322. <
  323. typename Point,
  324. int Dimension = -1,
  325. typename CSTag = void
  326. >
  327. struct equal_to
  328. {
  329. using first_argument_type = Point;
  330. using second_argument_type = Point;
  331. using result_type = bool;
  332. bool operator()(Point const& left, Point const& right) const
  333. {
  334. using strategy_type = typename strategy::compare::services::default_strategy
  335. <
  336. strategy::compare::equal_to,
  337. strategy::compare::equals_epsilon,
  338. Point, Point,
  339. Dimension,
  340. CSTag, CSTag
  341. >::type;
  342. return strategy_type::apply(left, right);
  343. }
  344. };
  345. template <int Dimension, typename CSTag>
  346. struct equal_to<void, Dimension, CSTag>
  347. {
  348. using result_type = bool;
  349. template <typename Point1, typename Point2>
  350. bool operator()(Point1 const& left, Point2 const& right) const
  351. {
  352. using strategy_type = typename strategy::compare::services::default_strategy
  353. <
  354. strategy::compare::equal_to,
  355. strategy::compare::equals_epsilon,
  356. Point1, Point2,
  357. Dimension,
  358. CSTag, CSTag
  359. >::type;
  360. return strategy_type::apply(left, right);
  361. }
  362. };
  363. template <typename Point, int Dimension>
  364. struct equal_to<Point, Dimension, void>
  365. {
  366. using first_argument_type = Point;
  367. using second_argument_type = Point;
  368. using result_type = bool;
  369. bool operator()(Point const& left, Point const& right) const
  370. {
  371. using strategy_type = typename strategy::compare::services::default_strategy
  372. <
  373. strategy::compare::equal_to,
  374. strategy::compare::equals_epsilon,
  375. Point, Point,
  376. Dimension
  377. >::type;
  378. return strategy_type::apply(left, right);
  379. }
  380. };
  381. template <int Dimension>
  382. struct equal_to<void, Dimension, void>
  383. {
  384. using result_type = bool;
  385. template <typename Point1, typename Point2>
  386. bool operator()(Point1 const& left, Point2 const& right) const
  387. {
  388. using strategy_type = typename strategy::compare::services::default_strategy
  389. <
  390. strategy::compare::equal_to,
  391. strategy::compare::equals_epsilon,
  392. Point1, Point2,
  393. Dimension
  394. >::type;
  395. return strategy_type::apply(left, right);
  396. }
  397. };
  398. }} // namespace boost::geometry
  399. #endif // BOOST_GEOMETRY_POLICIES_COMPARE_HPP