]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/detail/relate/interface.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / relate / interface.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4
5 // This file was modified by Oracle on 2013-2020.
6 // Modifications copyright (c) 2013-2020 Oracle and/or its affiliates.
7
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
13
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
16
17
18 #include <tuple>
19
20 #include <boost/variant/apply_visitor.hpp>
21 #include <boost/variant/static_visitor.hpp>
22 #include <boost/variant/variant_fwd.hpp>
23
24 #include <boost/geometry/algorithms/detail/relate/de9im.hpp>
25 #include <boost/geometry/algorithms/not_implemented.hpp>
26 #include <boost/geometry/core/coordinate_dimension.hpp>
27 #include <boost/geometry/core/tag.hpp>
28 #include <boost/geometry/core/tags.hpp>
29 #include <boost/geometry/core/topological_dimension.hpp>
30 #include <boost/geometry/geometries/concepts/check.hpp>
31 #include <boost/geometry/strategies/default_strategy.hpp>
32 #include <boost/geometry/strategies/detail.hpp>
33 #include <boost/geometry/strategies/relate/services.hpp>
34 #include <boost/geometry/util/sequence.hpp>
35 #include <boost/geometry/util/type_traits.hpp>
36
37
38 namespace boost { namespace geometry {
39
40
41 #ifndef DOXYGEN_NO_DETAIL
42 namespace detail { namespace relate {
43
44 // is_generic allows dispatch::relate to generate compile-time error
45 template <typename Geometry1, typename Geometry2>
46 struct is_generic
47 {
48 static const bool value = (util::is_polysegmental<Geometry1>::value
49 && util::is_polysegmental<Geometry2>::value)
50 ||
51 (util::is_point<Geometry1>::value
52 && util::is_polysegmental<Geometry2>::value)
53 ||
54 (util::is_polysegmental<Geometry1>::value
55 && util::is_point<Geometry2>::value);
56 };
57
58 }} // namespace detail::relate
59 #endif // DOXYGEN_NO_DETAIL
60
61
62 #ifndef DOXYGEN_NO_DISPATCH
63 namespace dispatch {
64
65
66 template <typename Geometry1,
67 typename Geometry2,
68 typename Tag1 = typename geometry::tag<Geometry1>::type,
69 typename Tag2 = typename geometry::tag<Geometry2>::type,
70 int TopDim1 = geometry::topological_dimension<Geometry1>::value,
71 int TopDim2 = geometry::topological_dimension<Geometry2>::value,
72 bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
73 >
74 struct relate : not_implemented<Tag1, Tag2>
75 {};
76
77 } // namespace dispatch
78 #endif // DOXYGEN_NO_DISPATCH
79
80 #ifndef DOXYGEN_NO_DETAIL
81 namespace detail { namespace relate {
82
83 template <typename Geometry1, typename Geometry2>
84 struct interruption_enabled
85 {
86 static const bool value =
87 dispatch::relate<Geometry1, Geometry2>::interruption_enabled;
88 };
89
90 template <typename Geometry1, typename Geometry2, typename Result>
91 struct result_handler_type
92 : not_implemented<Result>
93 {};
94
95 template <typename Geometry1, typename Geometry2>
96 struct result_handler_type<Geometry1, Geometry2, geometry::de9im::mask>
97 {
98 typedef mask_handler
99 <
100 geometry::de9im::mask,
101 interruption_enabled
102 <
103 Geometry1,
104 Geometry2
105 >::value
106 > type;
107 };
108
109 template <typename Geometry1, typename Geometry2, typename ...Masks>
110 struct result_handler_type<Geometry1, Geometry2, std::tuple<Masks...>>
111 {
112 typedef mask_handler
113 <
114 std::tuple<Masks...>,
115 interruption_enabled
116 <
117 Geometry1,
118 Geometry2
119 >::value
120 > type;
121 };
122
123 template <typename Geometry1, typename Geometry2,
124 char II, char IB, char IE,
125 char BI, char BB, char BE,
126 char EI, char EB, char EE>
127 struct result_handler_type
128 <
129 Geometry1,
130 Geometry2,
131 geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
132 >
133 {
134 typedef static_mask_handler
135 <
136 geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
137 interruption_enabled
138 <
139 Geometry1,
140 Geometry2
141 >::value
142 > type;
143 };
144
145 template <typename Geometry1, typename Geometry2, typename ...StaticMasks>
146 struct result_handler_type<Geometry1, Geometry2, util::type_sequence<StaticMasks...>>
147 {
148 typedef static_mask_handler
149 <
150 util::type_sequence<StaticMasks...>,
151 interruption_enabled
152 <
153 Geometry1,
154 Geometry2
155 >::value
156 > type;
157 };
158
159
160 }} // namespace detail::relate
161 #endif // DOXYGEN_NO_DETAIL
162
163 namespace resolve_strategy {
164
165
166 template
167 <
168 typename Strategy,
169 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
170 >
171 struct relate
172 {
173 template <typename Geometry1, typename Geometry2, typename ResultHandler>
174 static inline void apply(Geometry1 const& geometry1,
175 Geometry2 const& geometry2,
176 ResultHandler & handler,
177 Strategy const& strategy)
178 {
179 dispatch::relate
180 <
181 Geometry1,
182 Geometry2
183 >::apply(geometry1, geometry2, handler, strategy);
184 }
185 };
186
187 template <typename Strategy>
188 struct relate<Strategy, false>
189 {
190 template <typename Geometry1, typename Geometry2, typename ResultHandler>
191 static inline void apply(Geometry1 const& geometry1,
192 Geometry2 const& geometry2,
193 ResultHandler & handler,
194 Strategy const& strategy)
195 {
196 using strategies::relate::services::strategy_converter;
197 dispatch::relate
198 <
199 Geometry1,
200 Geometry2
201 >::apply(geometry1, geometry2, handler,
202 strategy_converter<Strategy>::get(strategy));
203 }
204 };
205
206 template <>
207 struct relate<default_strategy, false>
208 {
209 template <typename Geometry1, typename Geometry2, typename ResultHandler>
210 static inline void apply(Geometry1 const& geometry1,
211 Geometry2 const& geometry2,
212 ResultHandler & handler,
213 default_strategy)
214 {
215 typedef typename strategies::relate::services::default_strategy
216 <
217 Geometry1,
218 Geometry2
219 >::type strategy_type;
220
221 dispatch::relate
222 <
223 Geometry1,
224 Geometry2
225 >::apply(geometry1, geometry2, handler, strategy_type());
226 }
227 };
228
229 } // resolve_strategy
230
231 namespace resolve_variant {
232
233 template <typename Geometry1, typename Geometry2>
234 struct relate
235 {
236 template <typename Mask, typename Strategy>
237 static inline bool apply(Geometry1 const& geometry1,
238 Geometry2 const& geometry2,
239 Mask const& mask,
240 Strategy const& strategy)
241 {
242 concepts::check<Geometry1 const>();
243 concepts::check<Geometry2 const>();
244 assert_dimension_equal<Geometry1, Geometry2>();
245
246 typename detail::relate::result_handler_type
247 <
248 Geometry1,
249 Geometry2,
250 Mask
251 >::type handler(mask);
252
253 resolve_strategy::relate<Strategy>::apply(geometry1, geometry2, handler, strategy);
254
255 return handler.result();
256 }
257 };
258
259 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
260 struct relate<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
261 {
262 template <typename Mask, typename Strategy>
263 struct visitor : boost::static_visitor<bool>
264 {
265 Geometry2 const& m_geometry2;
266 Mask const& m_mask;
267 Strategy const& m_strategy;
268
269 visitor(Geometry2 const& geometry2, Mask const& mask, Strategy const& strategy)
270 : m_geometry2(geometry2), m_mask(mask), m_strategy(strategy) {}
271
272 template <typename Geometry1>
273 bool operator()(Geometry1 const& geometry1) const
274 {
275 return relate<Geometry1, Geometry2>
276 ::apply(geometry1, m_geometry2, m_mask, m_strategy);
277 }
278 };
279
280 template <typename Mask, typename Strategy>
281 static inline bool
282 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
283 Geometry2 const& geometry2,
284 Mask const& mask,
285 Strategy const& strategy)
286 {
287 return boost::apply_visitor(visitor<Mask, Strategy>(geometry2, mask, strategy), geometry1);
288 }
289 };
290
291 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
292 struct relate<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
293 {
294 template <typename Mask, typename Strategy>
295 struct visitor : boost::static_visitor<bool>
296 {
297 Geometry1 const& m_geometry1;
298 Mask const& m_mask;
299 Strategy const& m_strategy;
300
301 visitor(Geometry1 const& geometry1, Mask const& mask, Strategy const& strategy)
302 : m_geometry1(geometry1), m_mask(mask), m_strategy(strategy) {}
303
304 template <typename Geometry2>
305 bool operator()(Geometry2 const& geometry2) const
306 {
307 return relate<Geometry1, Geometry2>
308 ::apply(m_geometry1, geometry2, m_mask, m_strategy);
309 }
310 };
311
312 template <typename Mask, typename Strategy>
313 static inline bool
314 apply(Geometry1 const& geometry1,
315 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
316 Mask const& mask,
317 Strategy const& strategy)
318 {
319 return boost::apply_visitor(visitor<Mask, Strategy>(geometry1, mask, strategy), geometry2);
320 }
321 };
322
323 template <
324 BOOST_VARIANT_ENUM_PARAMS(typename T1),
325 BOOST_VARIANT_ENUM_PARAMS(typename T2)
326 >
327 struct relate<
328 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
329 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
330 >
331 {
332 template <typename Mask, typename Strategy>
333 struct visitor : boost::static_visitor<bool>
334 {
335 Mask const& m_mask;
336 Strategy const& m_strategy;
337
338 visitor(Mask const& mask, Strategy const& strategy)
339 : m_mask(mask), m_strategy(strategy) {}
340
341 template <typename Geometry1, typename Geometry2>
342 bool operator()(Geometry1 const& geometry1,
343 Geometry2 const& geometry2) const
344 {
345 return relate<Geometry1, Geometry2>
346 ::apply(geometry1, geometry2, m_mask, m_strategy);
347 }
348 };
349
350 template <typename Mask, typename Strategy>
351 static inline bool
352 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
353 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
354 Mask const& mask,
355 Strategy const& strategy)
356 {
357 return boost::apply_visitor(visitor<Mask, Strategy>(mask, strategy), geometry1, geometry2);
358 }
359 };
360
361 } // namespace resolve_variant
362
363 /*!
364 \brief Checks relation between a pair of geometries defined by a mask.
365 \ingroup relate
366 \tparam Geometry1 \tparam_geometry
367 \tparam Geometry2 \tparam_geometry
368 \tparam Mask An intersection model Mask type.
369 \tparam Strategy \tparam_strategy{Relate}
370 \param geometry1 \param_geometry
371 \param geometry2 \param_geometry
372 \param mask An intersection model mask object.
373 \param strategy \param_strategy{relate}
374 \return true if the relation is compatible with the mask, false otherwise.
375
376 \qbk{distinguish,with strategy}
377 \qbk{[include reference/algorithms/relate.qbk]}
378 */
379 template <typename Geometry1, typename Geometry2, typename Mask, typename Strategy>
380 inline bool relate(Geometry1 const& geometry1,
381 Geometry2 const& geometry2,
382 Mask const& mask,
383 Strategy const& strategy)
384 {
385 return resolve_variant::relate
386 <
387 Geometry1,
388 Geometry2
389 >::apply(geometry1, geometry2, mask, strategy);
390 }
391
392 /*!
393 \brief Checks relation between a pair of geometries defined by a mask.
394 \ingroup relate
395 \tparam Geometry1 \tparam_geometry
396 \tparam Geometry2 \tparam_geometry
397 \tparam Mask An intersection model Mask type.
398 \param geometry1 \param_geometry
399 \param geometry2 \param_geometry
400 \param mask An intersection model mask object.
401 \return true if the relation is compatible with the mask, false otherwise.
402
403 \qbk{[include reference/algorithms/relate.qbk]}
404 */
405 template <typename Geometry1, typename Geometry2, typename Mask>
406 inline bool relate(Geometry1 const& geometry1,
407 Geometry2 const& geometry2,
408 Mask const& mask)
409 {
410 return resolve_variant::relate
411 <
412 Geometry1,
413 Geometry2
414 >::apply(geometry1, geometry2, mask, default_strategy());
415 }
416
417 }} // namespace boost::geometry
418
419 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP