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