]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/strategies/concepts/within_concept.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / geometry / strategies / concepts / within_concept.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6
7 // This file was modified by Oracle on 2018-2020.
8 // Modifications copyright (c) 2018-2020 Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
11 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
12 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
13
14 // Use, modification and distribution is subject to the Boost Software License,
15 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
16 // http://www.boost.org/LICENSE_1_0.txt)
17
18 #ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
19 #define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
20
21
22 #include <type_traits>
23
24 #include <boost/concept_check.hpp>
25 #include <boost/core/ignore_unused.hpp>
26 #include <boost/function_types/result_type.hpp>
27
28 #include <boost/geometry/core/static_assert.hpp>
29 #include <boost/geometry/core/tag.hpp>
30 #include <boost/geometry/core/tag_cast.hpp>
31 #include <boost/geometry/core/tags.hpp>
32
33 #include <boost/geometry/geometries/concepts/box_concept.hpp>
34 #include <boost/geometry/geometries/concepts/point_concept.hpp>
35
36 #include <boost/geometry/strategies/detail.hpp>
37
38 #include <boost/geometry/util/parameter_type_of.hpp>
39
40
41 namespace boost { namespace geometry { namespace concepts
42 {
43
44
45 namespace detail
46 {
47
48
49 template
50 <
51 typename Point, typename Geometry, typename Strategy,
52 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
53 >
54 struct relate_strategy_dispatch
55 {
56 using type = decltype(std::declval<Strategy>().relate(
57 std::declval<Point>(), std::declval<Geometry>()));
58 };
59
60 template <typename Point, typename Geometry, typename Strategy>
61 struct relate_strategy_dispatch<Point, Geometry, Strategy, false>
62 {
63 using type = Strategy;
64 };
65
66 template
67 <
68 typename Point, typename Geometry, typename Strategy,
69 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
70 >
71 struct within_strategy_dispatch
72 {
73 using type = decltype(std::declval<Strategy>().within(
74 std::declval<Point>(), std::declval<Geometry>()));
75 };
76
77 template <typename Point, typename Geometry, typename Strategy>
78 struct within_strategy_dispatch<Point, Geometry, Strategy, false>
79 {
80 using type = Strategy;
81 };
82
83
84 } // namespace detail
85
86
87 /*!
88 \brief Checks strategy for within (point-in-polygon)
89 \ingroup within
90 */
91 template <typename Point, typename Polygonal, typename Strategy>
92 class WithinStrategyPolygonal
93 {
94 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
95
96 typedef typename geometry::point_type<Polygonal>::type point_of_segment;
97
98 // 0)
99 typedef typename concepts::detail::relate_strategy_dispatch
100 <
101 Point, Polygonal, Strategy
102 >::type strategy_type;
103
104 // 1) must define state_type
105 typedef typename strategy_type::state_type state_type;
106
107 struct checker
108 {
109 template <typename ApplyMethod, typename ResultMethod>
110 static void apply(ApplyMethod, ResultMethod)
111 {
112 typedef typename parameter_type_of
113 <
114 ApplyMethod, 0
115 >::type point_type;
116 typedef typename parameter_type_of
117 <
118 ApplyMethod, 1
119 >::type segment_point_type;
120
121 // CHECK: apply-arguments should both fulfill point concept
122 BOOST_CONCEPT_ASSERT
123 (
124 (concepts::ConstPoint<point_type>)
125 );
126
127 BOOST_CONCEPT_ASSERT
128 (
129 (concepts::ConstPoint<segment_point_type>)
130 );
131
132 // CHECK: return types (result: int, apply: bool)
133 BOOST_GEOMETRY_STATIC_ASSERT
134 (
135 (std::is_same
136 <
137 bool, typename boost::function_types::result_type<ApplyMethod>::type
138 >::value),
139 "Wrong return type of apply().",
140 bool, ApplyMethod
141 );
142 BOOST_GEOMETRY_STATIC_ASSERT
143 (
144 (std::is_same
145 <
146 int, typename boost::function_types::result_type<ResultMethod>::type
147 >::value),
148 "Wrong return type of result().",
149 int, ResultMethod
150 );
151
152
153 // CHECK: calling method apply and result
154 strategy_type const* str = 0;
155 state_type* st = 0;
156 point_type const* p = 0;
157 segment_point_type const* sp = 0;
158
159 bool b = str->apply(*p, *sp, *sp, *st);
160 int r = str->result(*st);
161
162 boost::ignore_unused(r, b, str);
163 }
164 };
165
166
167 public :
168 BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
169 {
170 checker::apply(&strategy_type::template apply<Point, point_of_segment>,
171 &strategy_type::result);
172 }
173 #endif
174 };
175
176 template <typename Point, typename Box, typename Strategy>
177 class WithinStrategyPointBox
178 {
179 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
180
181 // 0)
182 typedef typename concepts::detail::within_strategy_dispatch
183 <
184 Point, Box, Strategy
185 >::type strategy_type;
186
187 struct checker
188 {
189 template <typename ApplyMethod>
190 static void apply(ApplyMethod)
191 {
192 typedef typename parameter_type_of
193 <
194 ApplyMethod, 0
195 >::type point_type;
196 typedef typename parameter_type_of
197 <
198 ApplyMethod, 1
199 >::type box_type;
200
201 // CHECK: apply-arguments should fulfill point/box concept
202 BOOST_CONCEPT_ASSERT
203 (
204 (concepts::ConstPoint<point_type>)
205 );
206
207 BOOST_CONCEPT_ASSERT
208 (
209 (concepts::ConstBox<box_type>)
210 );
211
212 // CHECK: return types (apply: bool)
213 BOOST_GEOMETRY_STATIC_ASSERT
214 (
215 (std::is_same
216 <
217 bool,
218 typename boost::function_types::result_type<ApplyMethod>::type
219 >::value),
220 "Wrong return type of apply().",
221 bool, ApplyMethod
222 );
223
224
225 // CHECK: calling method apply
226 strategy_type const* str = 0;
227 point_type const* p = 0;
228 box_type const* bx = 0;
229
230 bool b = str->apply(*p, *bx);
231
232 boost::ignore_unused(b, str);
233 }
234 };
235
236
237 public :
238 BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
239 {
240 checker::apply(&strategy_type::template apply<Point, Box>);
241 }
242 #endif
243 };
244
245 template <typename Box1, typename Box2, typename Strategy>
246 class WithinStrategyBoxBox
247 {
248 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
249
250 // 0)
251 typedef typename concepts::detail::within_strategy_dispatch
252 <
253 Box1, Box2, Strategy
254 >::type strategy_type;
255
256 struct checker
257 {
258 template <typename ApplyMethod>
259 static void apply(ApplyMethod const&)
260 {
261 typedef typename parameter_type_of
262 <
263 ApplyMethod, 0
264 >::type box_type1;
265 typedef typename parameter_type_of
266 <
267 ApplyMethod, 1
268 >::type box_type2;
269
270 // CHECK: apply-arguments should both fulfill box concept
271 BOOST_CONCEPT_ASSERT
272 (
273 (concepts::ConstBox<box_type1>)
274 );
275
276 BOOST_CONCEPT_ASSERT
277 (
278 (concepts::ConstBox<box_type2>)
279 );
280
281 // CHECK: return types (apply: bool)
282 BOOST_GEOMETRY_STATIC_ASSERT
283 (
284 (std::is_same
285 <
286 bool,
287 typename boost::function_types::result_type<ApplyMethod>::type
288 >::value),
289 "Wrong return type of apply().",
290 bool, ApplyMethod
291 );
292
293
294 // CHECK: calling method apply
295 strategy_type const* str = 0;
296 box_type1 const* b1 = 0;
297 box_type2 const* b2 = 0;
298
299 bool b = str->apply(*b1, *b2);
300
301 boost::ignore_unused(b, str);
302 }
303 };
304
305
306 public :
307 BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
308 {
309 checker::apply(&strategy_type::template apply<Box1, Box2>);
310 }
311 #endif
312 };
313
314 // So now: boost::geometry::concepts::within
315 namespace within
316 {
317
318 #ifndef DOXYGEN_NO_DISPATCH
319 namespace dispatch
320 {
321
322 template
323 <
324 typename Geometry1, typename Geometry2,
325 typename FirstTag, typename SecondTag, typename CastedTag,
326 typename Strategy
327 >
328 struct check_within
329 {};
330
331
332 template
333 <
334 typename Geometry1, typename Geometry2,
335 typename AnyTag,
336 typename Strategy
337 >
338 struct check_within<Geometry1, Geometry2, point_tag, AnyTag, areal_tag, Strategy>
339 {
340 BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Geometry1, Geometry2, Strategy>) );
341 };
342
343
344 template <typename Geometry1, typename Geometry2, typename Strategy>
345 struct check_within<Geometry1, Geometry2, point_tag, box_tag, areal_tag, Strategy>
346 {
347 BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Geometry1, Geometry2, Strategy>) );
348 };
349
350 template <typename Geometry1, typename Geometry2, typename Strategy>
351 struct check_within<Geometry1, Geometry2, box_tag, box_tag, areal_tag, Strategy>
352 {
353 BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Geometry1, Geometry2, Strategy>) );
354 };
355
356
357 } // namespace dispatch
358 #endif
359
360
361 /*!
362 \brief Checks, in compile-time, the concept of any within-strategy
363 \ingroup concepts
364 */
365 template <typename Geometry1, typename Geometry2, typename Strategy>
366 inline void check()
367 {
368 dispatch::check_within
369 <
370 Geometry1,
371 Geometry2,
372 typename tag<Geometry1>::type,
373 typename tag<Geometry2>::type,
374 typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
375 Strategy
376 > c;
377 boost::ignore_unused(c);
378 }
379
380
381 }}}} // namespace boost::geometry::concepts::within
382
383
384 #endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP