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