comparable_distance_result.hpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2014-2020, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  4. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  5. // Licensed under the Boost Software License version 1.0.
  6. // http://www.boost.org/users/license.html
  7. #ifndef BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP
  8. #define BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP
  9. #include <boost/variant/variant_fwd.hpp>
  10. #include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
  11. #include <boost/geometry/core/point_type.hpp>
  12. #include <boost/geometry/strategies/default_strategy.hpp>
  13. #include <boost/geometry/strategies/distance.hpp>
  14. #include <boost/geometry/util/select_most_precise.hpp>
  15. #include <boost/geometry/util/sequence.hpp>
  16. #include <boost/geometry/util/type_traits.hpp>
  17. namespace boost { namespace geometry
  18. {
  19. namespace resolve_strategy
  20. {
  21. template
  22. <
  23. typename Geometry1, typename Geometry2, typename Strategy,
  24. bool AreGeometries = (util::is_geometry<Geometry1>::value
  25. && util::is_geometry<Geometry2>::value)
  26. >
  27. struct comparable_distance_result
  28. : strategy::distance::services::return_type
  29. <
  30. typename strategy::distance::services::comparable_type
  31. <
  32. Strategy
  33. >::type,
  34. typename point_type<Geometry1>::type,
  35. typename point_type<Geometry2>::type
  36. >
  37. {};
  38. template <typename Geometry1, typename Geometry2, bool AreGeometries>
  39. struct comparable_distance_result<Geometry1, Geometry2, default_strategy, AreGeometries>
  40. : comparable_distance_result
  41. <
  42. Geometry1,
  43. Geometry2,
  44. typename detail::distance::default_strategy
  45. <
  46. Geometry1, Geometry2
  47. >::type
  48. >
  49. {};
  50. // Workaround for VS2015
  51. #if defined(_MSC_VER) && (_MSC_VER < 1910)
  52. template <typename Geometry1, typename Geometry2, typename Strategy>
  53. struct comparable_distance_result<Geometry1, Geometry2, Strategy, false>
  54. {
  55. typedef int type;
  56. };
  57. template <typename Geometry1, typename Geometry2>
  58. struct comparable_distance_result<Geometry1, Geometry2, default_strategy, false>
  59. {
  60. typedef int type;
  61. };
  62. #endif
  63. } // namespace resolve_strategy
  64. #ifndef DOXYGEN_NO_DETAIL
  65. namespace detail { namespace distance
  66. {
  67. template <typename Strategy = geometry::default_strategy>
  68. struct more_precise_comparable_distance_result
  69. {
  70. template <typename Curr, typename Next>
  71. struct predicate
  72. : std::is_same
  73. <
  74. typename resolve_strategy::comparable_distance_result
  75. <
  76. typename util::sequence_element<0, Curr>::type,
  77. typename util::sequence_element<1, Curr>::type,
  78. Strategy
  79. >::type,
  80. typename geometry::select_most_precise
  81. <
  82. typename resolve_strategy::comparable_distance_result
  83. <
  84. typename util::sequence_element<0, Curr>::type,
  85. typename util::sequence_element<1, Curr>::type,
  86. Strategy
  87. >::type,
  88. typename resolve_strategy::comparable_distance_result
  89. <
  90. typename util::sequence_element<0, Next>::type,
  91. typename util::sequence_element<1, Next>::type,
  92. Strategy
  93. >::type
  94. >::type
  95. >
  96. {};
  97. };
  98. }} // namespace detail::distance
  99. #endif //DOXYGEN_NO_DETAIL
  100. namespace resolve_variant
  101. {
  102. template <typename Geometry1, typename Geometry2, typename Strategy>
  103. struct comparable_distance_result
  104. : resolve_strategy::comparable_distance_result
  105. <
  106. Geometry1,
  107. Geometry2,
  108. Strategy
  109. >
  110. {};
  111. template
  112. <
  113. typename Geometry1,
  114. BOOST_VARIANT_ENUM_PARAMS(typename T),
  115. typename Strategy
  116. >
  117. struct comparable_distance_result
  118. <
  119. Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy
  120. >
  121. {
  122. // Select the most precise distance strategy result type
  123. // for all variant type combinations.
  124. // TODO: We should ignore the combinations that are not valid
  125. // but is_implemented is not ready for prime time.
  126. typedef typename util::select_combination_element
  127. <
  128. util::type_sequence<Geometry1>,
  129. util::type_sequence<BOOST_VARIANT_ENUM_PARAMS(T)>,
  130. detail::distance::more_precise_comparable_distance_result
  131. <
  132. Strategy
  133. >::template predicate
  134. >::type elements;
  135. typedef typename resolve_strategy::comparable_distance_result
  136. <
  137. typename util::sequence_element<0, elements>::type,
  138. typename util::sequence_element<1, elements>::type,
  139. Strategy
  140. >::type type;
  141. };
  142. // Distance arguments are commutative
  143. template
  144. <
  145. BOOST_VARIANT_ENUM_PARAMS(typename T),
  146. typename Geometry2,
  147. typename Strategy
  148. >
  149. struct comparable_distance_result
  150. <
  151. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2, Strategy
  152. >
  153. : public comparable_distance_result
  154. <
  155. Geometry2, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy
  156. >
  157. {};
  158. template
  159. <
  160. BOOST_VARIANT_ENUM_PARAMS(typename T),
  161. BOOST_VARIANT_ENUM_PARAMS(typename U),
  162. typename Strategy
  163. >
  164. struct comparable_distance_result
  165. <
  166. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
  167. boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>,
  168. Strategy
  169. >
  170. {
  171. // Select the most precise distance strategy result type
  172. // for all variant type combinations.
  173. // TODO: We should ignore the combinations that are not valid
  174. // but is_implemented is not ready for prime time.
  175. typedef typename util::select_combination_element
  176. <
  177. util::type_sequence<BOOST_VARIANT_ENUM_PARAMS(T)>,
  178. util::type_sequence<BOOST_VARIANT_ENUM_PARAMS(U)>,
  179. detail::distance::more_precise_comparable_distance_result
  180. <
  181. Strategy
  182. >::template predicate
  183. >::type elements;
  184. typedef typename resolve_strategy::comparable_distance_result
  185. <
  186. typename util::sequence_element<0, elements>::type,
  187. typename util::sequence_element<1, elements>::type,
  188. Strategy
  189. >::type type;
  190. };
  191. } // namespace resolve_variant
  192. /*!
  193. \brief Meta-function defining return type of comparable_distance function
  194. \ingroup distance
  195. */
  196. template
  197. <
  198. typename Geometry1,
  199. typename Geometry2 = Geometry1,
  200. typename Strategy = void
  201. >
  202. struct comparable_distance_result
  203. : resolve_variant::comparable_distance_result
  204. <
  205. Geometry1, Geometry2, Strategy
  206. >
  207. {};
  208. template <typename Geometry1, typename Geometry2>
  209. struct comparable_distance_result<Geometry1, Geometry2, void>
  210. : comparable_distance_result<Geometry1, Geometry2, default_strategy>
  211. {};
  212. }} // namespace boost::geometry
  213. #endif // BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP