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