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