]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4
b32b8144
FG
5// This file was modified by Oracle on 2013, 2014, 2015, 2017.
6// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
7c673cae
FG
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>
b32b8144 32#include <boost/geometry/strategies/relate.hpp>
7c673cae
FG
33
34
35namespace boost { namespace geometry {
36
37
38#ifndef DOXYGEN_NO_DETAIL
39namespace detail { namespace relate {
40
41// Those are used only to allow dispatch::relate to produce compile-time error
42
43template <typename Geometry,
44 typename Tag = typename geometry::tag<Geometry>::type>
45struct 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
55template <typename Geometry1,
56 typename Geometry2,
57 typename Tag1 = typename geometry::tag<Geometry1>::type,
58 typename Tag2 = typename geometry::tag<Geometry2>::type>
59struct is_generic
60{
61 static const bool value = is_supported_by_generic<Geometry1>::value
62 && is_supported_by_generic<Geometry2>::value;
63};
64
65
66template <typename Point, typename Geometry, typename Tag>
67struct is_generic<Point, Geometry, point_tag, Tag>
68{
69 static const bool value = is_supported_by_generic<Geometry>::value;
70};
71
72template <typename Geometry, typename Point, typename Tag>
73struct is_generic<Geometry, Point, Tag, point_tag>
74{
75 static const bool value = is_supported_by_generic<Geometry>::value;
76};
77
78template <typename Point1, typename Point2>
79struct 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
90namespace dispatch {
91
92
93template <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>
101struct relate : not_implemented<Tag1, Tag2>
102{};
103
104} // namespace dispatch
105#endif // DOXYGEN_NO_DISPATCH
106
107#ifndef DOXYGEN_NO_DETAIL
108namespace detail { namespace relate {
109
110template <typename Geometry1, typename Geometry2>
111struct interruption_enabled
112{
113 static const bool value =
114 dispatch::relate<Geometry1, Geometry2>::interruption_enabled;
115};
116
117template <typename Geometry1,
118 typename Geometry2,
119 typename Result,
120 bool IsSequence = boost::mpl::is_sequence<Result>::value>
121struct result_handler_type
122 : not_implemented<Result>
123{};
124
125template <typename Geometry1, typename Geometry2>
126struct 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
139template <typename Geometry1, typename Geometry2, typename Head, typename Tail>
140struct 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
153template <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>
157struct 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
176template <typename Geometry1, typename Geometry2, typename StaticSequence>
177struct 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
b32b8144 190
7c673cae
FG
191}} // namespace detail::relate
192#endif // DOXYGEN_NO_DETAIL
193
b32b8144
FG
194namespace resolve_strategy {
195
196struct 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
7c673cae
FG
233namespace resolve_variant {
234
235template <typename Geometry1, typename Geometry2>
236struct relate
237{
b32b8144 238 template <typename Mask, typename Strategy>
7c673cae
FG
239 static inline bool apply(Geometry1 const& geometry1,
240 Geometry2 const& geometry2,
b32b8144
FG
241 Mask const& mask,
242 Strategy const& strategy)
7c673cae
FG
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
b32b8144 255 resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy);
7c673cae
FG
256
257 return handler.result();
258 }
259};
260
261template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
262struct relate<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
263{
b32b8144 264 template <typename Mask, typename Strategy>
7c673cae
FG
265 struct visitor : boost::static_visitor<bool>
266 {
267 Geometry2 const& m_geometry2;
268 Mask const& m_mask;
b32b8144 269 Strategy const& m_strategy;
7c673cae 270
b32b8144
FG
271 visitor(Geometry2 const& geometry2, Mask const& mask, Strategy const& strategy)
272 : m_geometry2(geometry2), m_mask(mask), m_strategy(strategy) {}
7c673cae
FG
273
274 template <typename Geometry1>
275 bool operator()(Geometry1 const& geometry1) const
276 {
277 return relate<Geometry1, Geometry2>
b32b8144 278 ::apply(geometry1, m_geometry2, m_mask, m_strategy);
7c673cae
FG
279 }
280 };
281
b32b8144 282 template <typename Mask, typename Strategy>
7c673cae
FG
283 static inline bool
284 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
285 Geometry2 const& geometry2,
b32b8144
FG
286 Mask const& mask,
287 Strategy const& strategy)
7c673cae 288 {
b32b8144 289 return boost::apply_visitor(visitor<Mask, Strategy>(geometry2, mask, strategy), geometry1);
7c673cae
FG
290 }
291};
292
293template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
294struct relate<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
295{
b32b8144 296 template <typename Mask, typename Strategy>
7c673cae
FG
297 struct visitor : boost::static_visitor<bool>
298 {
299 Geometry1 const& m_geometry1;
300 Mask const& m_mask;
b32b8144 301 Strategy const& m_strategy;
7c673cae 302
b32b8144
FG
303 visitor(Geometry1 const& geometry1, Mask const& mask, Strategy const& strategy)
304 : m_geometry1(geometry1), m_mask(mask), m_strategy(strategy) {}
7c673cae
FG
305
306 template <typename Geometry2>
307 bool operator()(Geometry2 const& geometry2) const
308 {
309 return relate<Geometry1, Geometry2>
b32b8144 310 ::apply(m_geometry1, geometry2, m_mask, m_strategy);
7c673cae
FG
311 }
312 };
313
b32b8144 314 template <typename Mask, typename Strategy>
7c673cae
FG
315 static inline bool
316 apply(Geometry1 const& geometry1,
317 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
b32b8144
FG
318 Mask const& mask,
319 Strategy const& strategy)
7c673cae 320 {
b32b8144 321 return boost::apply_visitor(visitor<Mask, Strategy>(geometry1, mask, strategy), geometry2);
7c673cae
FG
322 }
323};
324
325template <
326 BOOST_VARIANT_ENUM_PARAMS(typename T1),
327 BOOST_VARIANT_ENUM_PARAMS(typename T2)
328>
329struct relate<
330 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
331 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
332>
333{
b32b8144 334 template <typename Mask, typename Strategy>
7c673cae
FG
335 struct visitor : boost::static_visitor<bool>
336 {
337 Mask const& m_mask;
b32b8144 338 Strategy const& m_strategy;
7c673cae 339
b32b8144
FG
340 visitor(Mask const& mask, Strategy const& strategy)
341 : m_mask(mask), m_strategy(strategy) {}
7c673cae
FG
342
343 template <typename Geometry1, typename Geometry2>
344 bool operator()(Geometry1 const& geometry1,
345 Geometry2 const& geometry2) const
346 {
347 return relate<Geometry1, Geometry2>
b32b8144 348 ::apply(geometry1, geometry2, m_mask, m_strategy);
7c673cae
FG
349 }
350 };
351
b32b8144 352 template <typename Mask, typename Strategy>
7c673cae
FG
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,
b32b8144
FG
356 Mask const& mask,
357 Strategy const& strategy)
7c673cae 358 {
b32b8144 359 return boost::apply_visitor(visitor<Mask, Strategy>(mask, strategy), geometry1, geometry2);
7c673cae
FG
360 }
361};
362
363} // namespace resolve_variant
364
b32b8144
FG
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 */
381template <typename Geometry1, typename Geometry2, typename Mask, typename Strategy>
382inline 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
7c673cae
FG
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 */
407template <typename Geometry1, typename Geometry2, typename Mask>
408inline bool relate(Geometry1 const& geometry1,
409 Geometry2 const& geometry2,
410 Mask const& mask)
411{
412 return resolve_variant::relate
413 <
414 Geometry1,
415 Geometry2
b32b8144 416 >::apply(geometry1, geometry2, mask, default_strategy());
7c673cae
FG
417}
418
419}} // namespace boost::geometry
420
421#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP