distance_result.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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-2020.
  8. // Modifications copyright (c) 2014-2020, 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/variant/variant_fwd.hpp>
  19. #include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
  20. #include <boost/geometry/core/point_type.hpp>
  21. #include <boost/geometry/strategies/default_strategy.hpp>
  22. #include <boost/geometry/strategies/distance.hpp>
  23. #include <boost/geometry/util/select_most_precise.hpp>
  24. #include <boost/geometry/util/sequence.hpp>
  25. #include <boost/geometry/util/type_traits.hpp>
  26. namespace boost { namespace geometry
  27. {
  28. namespace resolve_strategy
  29. {
  30. template
  31. <
  32. typename Geometry1, typename Geometry2, typename Strategy,
  33. bool AreGeometries = (util::is_geometry<Geometry1>::value
  34. && util::is_geometry<Geometry2>::value)
  35. >
  36. struct distance_result
  37. : strategy::distance::services::return_type
  38. <
  39. Strategy,
  40. typename point_type<Geometry1>::type,
  41. typename point_type<Geometry2>::type
  42. >
  43. {};
  44. template <typename Geometry1, typename Geometry2, bool AreGeometries>
  45. struct distance_result<Geometry1, Geometry2, default_strategy, AreGeometries>
  46. : distance_result
  47. <
  48. Geometry1,
  49. Geometry2,
  50. typename detail::distance::default_strategy
  51. <
  52. Geometry1, Geometry2
  53. >::type
  54. >
  55. {};
  56. // Workaround for VS2015
  57. #if defined(_MSC_VER) && (_MSC_VER < 1910)
  58. template <typename Geometry1, typename Geometry2, typename Strategy>
  59. struct distance_result<Geometry1, Geometry2, Strategy, false>
  60. {
  61. typedef int type;
  62. };
  63. template <typename Geometry1, typename Geometry2>
  64. struct distance_result<Geometry1, Geometry2, default_strategy, false>
  65. {
  66. typedef int type;
  67. };
  68. #endif
  69. } // namespace resolve_strategy
  70. #ifndef DOXYGEN_NO_DETAIL
  71. namespace detail { namespace distance
  72. {
  73. template <typename Strategy = geometry::default_strategy>
  74. struct more_precise_distance_result
  75. {
  76. template <typename Curr, typename Next>
  77. struct predicate
  78. : std::is_same
  79. <
  80. typename resolve_strategy::distance_result
  81. <
  82. typename util::sequence_element<0, Curr>::type,
  83. typename util::sequence_element<1, Curr>::type,
  84. Strategy
  85. >::type,
  86. typename geometry::select_most_precise
  87. <
  88. typename resolve_strategy::distance_result
  89. <
  90. typename util::sequence_element<0, Curr>::type,
  91. typename util::sequence_element<1, Curr>::type,
  92. Strategy
  93. >::type,
  94. typename resolve_strategy::distance_result
  95. <
  96. typename util::sequence_element<0, Next>::type,
  97. typename util::sequence_element<1, Next>::type,
  98. Strategy
  99. >::type
  100. >::type
  101. >
  102. {};
  103. };
  104. }} // namespace detail::distance
  105. #endif //DOXYGEN_NO_DETAIL
  106. namespace resolve_variant
  107. {
  108. template <typename Geometry1, typename Geometry2, typename Strategy>
  109. struct distance_result
  110. : resolve_strategy::distance_result
  111. <
  112. Geometry1,
  113. Geometry2,
  114. Strategy
  115. >
  116. {};
  117. template
  118. <
  119. typename Geometry1,
  120. BOOST_VARIANT_ENUM_PARAMS(typename T),
  121. typename Strategy
  122. >
  123. struct distance_result
  124. <
  125. Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy
  126. >
  127. {
  128. // Select the most precise distance strategy result type
  129. // for all variant type combinations.
  130. // TODO: We should ignore the combinations that are not valid
  131. // but is_implemented is not ready for prime time.
  132. typedef typename util::select_combination_element
  133. <
  134. util::type_sequence<Geometry1>,
  135. util::type_sequence<BOOST_VARIANT_ENUM_PARAMS(T)>,
  136. detail::distance::more_precise_distance_result<Strategy>::template predicate
  137. >::type elements;
  138. typedef typename resolve_strategy::distance_result
  139. <
  140. typename util::sequence_element<0, elements>::type,
  141. typename util::sequence_element<1, elements>::type,
  142. Strategy
  143. >::type type;
  144. };
  145. // Distance arguments are commutative
  146. template
  147. <
  148. BOOST_VARIANT_ENUM_PARAMS(typename T),
  149. typename Geometry2,
  150. typename Strategy
  151. >
  152. struct distance_result
  153. <
  154. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2, Strategy
  155. >
  156. : public distance_result
  157. <
  158. Geometry2, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Strategy
  159. >
  160. {};
  161. template
  162. <
  163. BOOST_VARIANT_ENUM_PARAMS(typename T),
  164. BOOST_VARIANT_ENUM_PARAMS(typename U),
  165. typename Strategy
  166. >
  167. struct distance_result
  168. <
  169. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
  170. boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>,
  171. Strategy
  172. >
  173. {
  174. // Select the most precise distance strategy result type
  175. // for all variant type combinations.
  176. // TODO: We should ignore the combinations that are not valid
  177. // but is_implemented is not ready for prime time.
  178. typedef typename util::select_combination_element
  179. <
  180. util::type_sequence<BOOST_VARIANT_ENUM_PARAMS(T)>,
  181. util::type_sequence<BOOST_VARIANT_ENUM_PARAMS(U)>,
  182. detail::distance::more_precise_distance_result<Strategy>::template predicate
  183. >::type elements;
  184. typedef typename resolve_strategy::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 distance function
  194. \ingroup distance
  195. \note The strategy defines the return-type (so this situation is different
  196. from length, where distance is sqr/sqrt, but length always squared)
  197. */
  198. template
  199. <
  200. typename Geometry1,
  201. typename Geometry2 = Geometry1,
  202. typename Strategy = void
  203. >
  204. struct distance_result
  205. : resolve_variant::distance_result<Geometry1, Geometry2, Strategy>
  206. {};
  207. template <typename Geometry1, typename Geometry2>
  208. struct distance_result<Geometry1, Geometry2, void>
  209. : distance_result<Geometry1, Geometry2, default_strategy>
  210. {};
  211. }} // namespace boost::geometry
  212. #endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP