]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4
20effc67
TL
5// This file was modified by Oracle on 2013-2020.
6// Modifications copyright (c) 2013-2020 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
20effc67
TL
18#include <tuple>
19
7c673cae
FG
20#include <boost/variant/apply_visitor.hpp>
21#include <boost/variant/static_visitor.hpp>
22#include <boost/variant/variant_fwd.hpp>
23
20effc67
TL
24#include <boost/geometry/algorithms/detail/relate/de9im.hpp>
25#include <boost/geometry/algorithms/not_implemented.hpp>
7c673cae
FG
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>
7c673cae
FG
30#include <boost/geometry/geometries/concepts/check.hpp>
31#include <boost/geometry/strategies/default_strategy.hpp>
1e59de90
TL
32#include <boost/geometry/strategies/detail.hpp>
33#include <boost/geometry/strategies/relate/services.hpp>
20effc67
TL
34#include <boost/geometry/util/sequence.hpp>
35#include <boost/geometry/util/type_traits.hpp>
7c673cae
FG
36
37
38namespace boost { namespace geometry {
39
40
41#ifndef DOXYGEN_NO_DETAIL
42namespace detail { namespace relate {
43
20effc67
TL
44// is_generic allows dispatch::relate to generate compile-time error
45template <typename Geometry1, typename Geometry2>
7c673cae
FG
46struct is_generic
47{
20effc67
TL
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);
7c673cae
FG
56};
57
7c673cae
FG
58}} // namespace detail::relate
59#endif // DOXYGEN_NO_DETAIL
60
61
62#ifndef DOXYGEN_NO_DISPATCH
63namespace dispatch {
64
65
66template <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>
74struct relate : not_implemented<Tag1, Tag2>
75{};
76
77} // namespace dispatch
78#endif // DOXYGEN_NO_DISPATCH
79
80#ifndef DOXYGEN_NO_DETAIL
81namespace detail { namespace relate {
82
83template <typename Geometry1, typename Geometry2>
84struct interruption_enabled
85{
86 static const bool value =
87 dispatch::relate<Geometry1, Geometry2>::interruption_enabled;
88};
89
20effc67 90template <typename Geometry1, typename Geometry2, typename Result>
7c673cae
FG
91struct result_handler_type
92 : not_implemented<Result>
93{};
94
95template <typename Geometry1, typename Geometry2>
20effc67 96struct result_handler_type<Geometry1, Geometry2, geometry::de9im::mask>
7c673cae
FG
97{
98 typedef mask_handler
99 <
100 geometry::de9im::mask,
101 interruption_enabled
102 <
103 Geometry1,
104 Geometry2
105 >::value
106 > type;
107};
108
20effc67
TL
109template <typename Geometry1, typename Geometry2, typename ...Masks>
110struct result_handler_type<Geometry1, Geometry2, std::tuple<Masks...>>
7c673cae
FG
111{
112 typedef mask_handler
113 <
20effc67 114 std::tuple<Masks...>,
7c673cae
FG
115 interruption_enabled
116 <
117 Geometry1,
118 Geometry2
119 >::value
120 > type;
121};
122
123template <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>
127struct result_handler_type
128 <
129 Geometry1,
130 Geometry2,
20effc67 131 geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
7c673cae
FG
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
20effc67
TL
145template <typename Geometry1, typename Geometry2, typename ...StaticMasks>
146struct result_handler_type<Geometry1, Geometry2, util::type_sequence<StaticMasks...>>
7c673cae
FG
147{
148 typedef static_mask_handler
149 <
20effc67 150 util::type_sequence<StaticMasks...>,
7c673cae
FG
151 interruption_enabled
152 <
153 Geometry1,
154 Geometry2
155 >::value
156 > type;
157};
158
b32b8144 159
7c673cae
FG
160}} // namespace detail::relate
161#endif // DOXYGEN_NO_DETAIL
162
b32b8144
FG
163namespace resolve_strategy {
164
1e59de90
TL
165
166template
167<
168 typename Strategy,
169 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
170>
b32b8144
FG
171struct relate
172{
1e59de90 173 template <typename Geometry1, typename Geometry2, typename ResultHandler>
b32b8144
FG
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 }
1e59de90 185};
b32b8144 186
1e59de90
TL
187template <typename Strategy>
188struct 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
206template <>
207struct relate<default_strategy, false>
208{
b32b8144
FG
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 {
1e59de90 215 typedef typename strategies::relate::services::default_strategy
b32b8144
FG
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
7c673cae
FG
231namespace resolve_variant {
232
233template <typename Geometry1, typename Geometry2>
234struct relate
235{
b32b8144 236 template <typename Mask, typename Strategy>
7c673cae
FG
237 static inline bool apply(Geometry1 const& geometry1,
238 Geometry2 const& geometry2,
b32b8144
FG
239 Mask const& mask,
240 Strategy const& strategy)
7c673cae
FG
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
1e59de90 253 resolve_strategy::relate<Strategy>::apply(geometry1, geometry2, handler, strategy);
7c673cae
FG
254
255 return handler.result();
256 }
257};
258
259template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
260struct relate<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
261{
b32b8144 262 template <typename Mask, typename Strategy>
7c673cae
FG
263 struct visitor : boost::static_visitor<bool>
264 {
265 Geometry2 const& m_geometry2;
266 Mask const& m_mask;
b32b8144 267 Strategy const& m_strategy;
7c673cae 268
b32b8144
FG
269 visitor(Geometry2 const& geometry2, Mask const& mask, Strategy const& strategy)
270 : m_geometry2(geometry2), m_mask(mask), m_strategy(strategy) {}
7c673cae
FG
271
272 template <typename Geometry1>
273 bool operator()(Geometry1 const& geometry1) const
274 {
275 return relate<Geometry1, Geometry2>
b32b8144 276 ::apply(geometry1, m_geometry2, m_mask, m_strategy);
7c673cae
FG
277 }
278 };
279
b32b8144 280 template <typename Mask, typename Strategy>
7c673cae
FG
281 static inline bool
282 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
283 Geometry2 const& geometry2,
b32b8144
FG
284 Mask const& mask,
285 Strategy const& strategy)
7c673cae 286 {
b32b8144 287 return boost::apply_visitor(visitor<Mask, Strategy>(geometry2, mask, strategy), geometry1);
7c673cae
FG
288 }
289};
290
291template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
292struct relate<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
293{
b32b8144 294 template <typename Mask, typename Strategy>
7c673cae
FG
295 struct visitor : boost::static_visitor<bool>
296 {
297 Geometry1 const& m_geometry1;
298 Mask const& m_mask;
b32b8144 299 Strategy const& m_strategy;
7c673cae 300
b32b8144
FG
301 visitor(Geometry1 const& geometry1, Mask const& mask, Strategy const& strategy)
302 : m_geometry1(geometry1), m_mask(mask), m_strategy(strategy) {}
7c673cae
FG
303
304 template <typename Geometry2>
305 bool operator()(Geometry2 const& geometry2) const
306 {
307 return relate<Geometry1, Geometry2>
b32b8144 308 ::apply(m_geometry1, geometry2, m_mask, m_strategy);
7c673cae
FG
309 }
310 };
311
b32b8144 312 template <typename Mask, typename Strategy>
7c673cae
FG
313 static inline bool
314 apply(Geometry1 const& geometry1,
315 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
b32b8144
FG
316 Mask const& mask,
317 Strategy const& strategy)
7c673cae 318 {
b32b8144 319 return boost::apply_visitor(visitor<Mask, Strategy>(geometry1, mask, strategy), geometry2);
7c673cae
FG
320 }
321};
322
323template <
324 BOOST_VARIANT_ENUM_PARAMS(typename T1),
325 BOOST_VARIANT_ENUM_PARAMS(typename T2)
326>
327struct relate<
328 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
329 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
330>
331{
b32b8144 332 template <typename Mask, typename Strategy>
7c673cae
FG
333 struct visitor : boost::static_visitor<bool>
334 {
335 Mask const& m_mask;
b32b8144 336 Strategy const& m_strategy;
7c673cae 337
b32b8144
FG
338 visitor(Mask const& mask, Strategy const& strategy)
339 : m_mask(mask), m_strategy(strategy) {}
7c673cae
FG
340
341 template <typename Geometry1, typename Geometry2>
342 bool operator()(Geometry1 const& geometry1,
343 Geometry2 const& geometry2) const
344 {
345 return relate<Geometry1, Geometry2>
b32b8144 346 ::apply(geometry1, geometry2, m_mask, m_strategy);
7c673cae
FG
347 }
348 };
349
b32b8144 350 template <typename Mask, typename Strategy>
7c673cae
FG
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,
b32b8144
FG
354 Mask const& mask,
355 Strategy const& strategy)
7c673cae 356 {
b32b8144 357 return boost::apply_visitor(visitor<Mask, Strategy>(mask, strategy), geometry1, geometry2);
7c673cae
FG
358 }
359};
360
361} // namespace resolve_variant
362
b32b8144
FG
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 */
379template <typename Geometry1, typename Geometry2, typename Mask, typename Strategy>
380inline 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
7c673cae
FG
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 */
405template <typename Geometry1, typename Geometry2, typename Mask>
406inline bool relate(Geometry1 const& geometry1,
407 Geometry2 const& geometry2,
408 Mask const& mask)
409{
410 return resolve_variant::relate
411 <
412 Geometry1,
413 Geometry2
b32b8144 414 >::apply(geometry1, geometry2, mask, default_strategy());
7c673cae
FG
415}
416
417}} // namespace boost::geometry
418
419#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP