distance_result.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
  5. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
  6. // Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
  7. // This file was modified by Oracle on 2014-2021.
  8. // Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
  9. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  10. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  11. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  12. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  13. // Use, modification and distribution is subject to the Boost Software License,
  14. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  15. // http://www.boost.org/LICENSE_1_0.txt)
  16. #ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP
  17. #define BOOST_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP
  18. #include <boost/geometry/algorithms/detail/select_geometry_type.hpp>
  19. #include <boost/geometry/core/point_type.hpp>
  20. #include <boost/geometry/core/reverse_dispatch.hpp>
  21. #include <boost/geometry/strategies/default_strategy.hpp>
  22. #include <boost/geometry/strategies/detail.hpp>
  23. #include <boost/geometry/strategies/distance.hpp>
  24. #include <boost/geometry/strategies/distance/services.hpp>
  25. #include <boost/geometry/util/select_most_precise.hpp>
  26. #include <boost/geometry/util/sequence.hpp>
  27. #include <boost/geometry/util/type_traits.hpp>
  28. namespace boost { namespace geometry
  29. {
  30. namespace resolve_strategy
  31. {
  32. // TODO: This utility could be entirely implemented as:
  33. // decltype(geometry::distance(std::declval<Geometry1>(), std::declval<Geometry2>(), std::declval<Strategy>()))
  34. // however then the algorithm would have to be compiled.
  35. template
  36. <
  37. typename Geometry1, typename Geometry2, typename Strategy,
  38. bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
  39. >
  40. struct distance_result_strategy2_type
  41. {
  42. typedef decltype(std::declval<Strategy>().distance(
  43. std::declval<Geometry1>(), std::declval<Geometry2>())) type;
  44. };
  45. template <typename Geometry1, typename Geometry2, typename Strategy>
  46. struct distance_result_strategy2_type<Geometry1, Geometry2, Strategy, false>
  47. {
  48. typedef Strategy type;
  49. };
  50. template
  51. <
  52. typename Geometry1, typename Geometry2, typename Strategy,
  53. bool Reverse = reverse_dispatch<Geometry1, Geometry2>::value
  54. >
  55. struct distance_result_strategy_type
  56. : distance_result_strategy2_type<Geometry1, Geometry2, Strategy>
  57. {};
  58. template <typename Geometry1, typename Geometry2, typename Strategy>
  59. struct distance_result_strategy_type<Geometry1, Geometry2, Strategy, true>
  60. : distance_result_strategy_type<Geometry2, Geometry1, Strategy, false>
  61. {};
  62. template <typename Geometry1, typename Geometry2, typename Strategy>
  63. struct distance_result
  64. : strategy::distance::services::return_type
  65. <
  66. typename distance_result_strategy_type<Geometry1, Geometry2, Strategy>::type,
  67. typename point_type<Geometry1>::type,
  68. typename point_type<Geometry2>::type
  69. >
  70. {};
  71. template <typename Geometry1, typename Geometry2>
  72. struct distance_result<Geometry1, Geometry2, default_strategy>
  73. : distance_result
  74. <
  75. Geometry1,
  76. Geometry2,
  77. typename strategies::distance::services::default_strategy
  78. <
  79. Geometry1, Geometry2
  80. >::type
  81. >
  82. {};
  83. } // namespace resolve_strategy
  84. #ifndef DOXYGEN_NO_DETAIL
  85. namespace detail { namespace distance
  86. {
  87. template <typename Strategy = geometry::default_strategy>
  88. struct more_precise_distance_result
  89. {
  90. template <typename Curr, typename Next>
  91. struct predicate
  92. : std::is_same
  93. <
  94. typename resolve_strategy::distance_result
  95. <
  96. typename util::sequence_element<0, Curr>::type,
  97. typename util::sequence_element<1, Curr>::type,
  98. Strategy
  99. >::type,
  100. typename geometry::select_most_precise
  101. <
  102. typename resolve_strategy::distance_result
  103. <
  104. typename util::sequence_element<0, Curr>::type,
  105. typename util::sequence_element<1, Curr>::type,
  106. Strategy
  107. >::type,
  108. typename resolve_strategy::distance_result
  109. <
  110. typename util::sequence_element<0, Next>::type,
  111. typename util::sequence_element<1, Next>::type,
  112. Strategy
  113. >::type
  114. >::type
  115. >
  116. {};
  117. };
  118. }} // namespace detail::distance
  119. #endif //DOXYGEN_NO_DETAIL
  120. namespace resolve_dynamic
  121. {
  122. template
  123. <
  124. typename Geometry1, typename Geometry2, typename Strategy,
  125. bool IsDynamicOrCollection = util::is_dynamic_geometry<Geometry1>::value
  126. || util::is_dynamic_geometry<Geometry2>::value
  127. || util::is_geometry_collection<Geometry1>::value
  128. || util::is_geometry_collection<Geometry2>::value
  129. >
  130. struct distance_result
  131. : resolve_strategy::distance_result
  132. <
  133. Geometry1,
  134. Geometry2,
  135. Strategy
  136. >
  137. {};
  138. template <typename Geometry1, typename Geometry2, typename Strategy>
  139. struct distance_result<Geometry1, Geometry2, Strategy, true>
  140. {
  141. // Select the most precise distance strategy result type
  142. // for all variant type combinations.
  143. // TODO: We should ignore the combinations that are not valid
  144. // but is_implemented is not ready for prime time.
  145. using selected_types = typename detail::select_geometry_types
  146. <
  147. Geometry1, Geometry2,
  148. detail::distance::more_precise_distance_result<Strategy>::template predicate
  149. >::type;
  150. using type = typename resolve_strategy::distance_result
  151. <
  152. typename util::sequence_element<0, selected_types>::type,
  153. typename util::sequence_element<1, selected_types>::type,
  154. Strategy
  155. >::type;
  156. };
  157. } // namespace resolve_dynamic
  158. /*!
  159. \brief Meta-function defining return type of distance function
  160. \ingroup distance
  161. \note The strategy defines the return-type (so this situation is different
  162. from length, where distance is sqr/sqrt, but length always squared)
  163. */
  164. template
  165. <
  166. typename Geometry1,
  167. typename Geometry2 = Geometry1,
  168. typename Strategy = void
  169. >
  170. struct distance_result
  171. : resolve_dynamic::distance_result<Geometry1, Geometry2, Strategy>
  172. {};
  173. template <typename Geometry1, typename Geometry2>
  174. struct distance_result<Geometry1, Geometry2, void>
  175. : distance_result<Geometry1, Geometry2, default_strategy>
  176. {};
  177. }} // namespace boost::geometry
  178. #endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP