• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, 2019.
8 // Modifications copyright (c) 2018, 2019 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 
23 #include <boost/concept_check.hpp>
24 #include <boost/core/ignore_unused.hpp>
25 #include <boost/function_types/result_type.hpp>
26 
27 #include <boost/geometry/core/tag.hpp>
28 #include <boost/geometry/core/tag_cast.hpp>
29 #include <boost/geometry/core/tags.hpp>
30 
31 #include <boost/geometry/geometries/concepts/box_concept.hpp>
32 #include <boost/geometry/geometries/concepts/point_concept.hpp>
33 
34 #include <boost/geometry/util/parameter_type_of.hpp>
35 
36 
37 namespace boost { namespace geometry { namespace concepts
38 {
39 
40 
41 /*!
42 \brief Checks strategy for within (point-in-polygon)
43 \ingroup within
44 */
45 template <typename Point, typename Polygonal, typename Strategy>
46 class WithinStrategyPolygonal
47 {
48 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
49 
50     typedef typename geometry::point_type<Polygonal>::type point_of_segment;
51 
52     // 1) must define state_type
53     typedef typename Strategy::state_type state_type;
54 
55     struct checker
56     {
57         template <typename ApplyMethod, typename ResultMethod>
applyboost::geometry::concepts::WithinStrategyPolygonal::checker58         static void apply(ApplyMethod, ResultMethod)
59         {
60             typedef typename parameter_type_of
61                 <
62                     ApplyMethod, 0
63                 >::type point_type;
64             typedef typename parameter_type_of
65                 <
66                     ApplyMethod, 1
67                 >::type segment_point_type;
68 
69             // CHECK: apply-arguments should both fulfill point concept
70             BOOST_CONCEPT_ASSERT
71                 (
72                     (concepts::ConstPoint<point_type>)
73                 );
74 
75             BOOST_CONCEPT_ASSERT
76                 (
77                     (concepts::ConstPoint<segment_point_type>)
78                 );
79 
80             // CHECK: return types (result: int, apply: bool)
81             BOOST_MPL_ASSERT_MSG
82                 (
83                     (boost::is_same
84                         <
85                             bool, typename boost::function_types::result_type<ApplyMethod>::type
86                         >::type::value),
87                     WRONG_RETURN_TYPE_OF_APPLY
88                     , (bool)
89                 );
90             BOOST_MPL_ASSERT_MSG
91                 (
92                     (boost::is_same
93                         <
94                             int, typename boost::function_types::result_type<ResultMethod>::type
95                         >::type::value),
96                     WRONG_RETURN_TYPE_OF_RESULT
97                     , (int)
98                 );
99 
100 
101             // CHECK: calling method apply and result
102             Strategy const* str = 0;
103             state_type* st = 0;
104             point_type const* p = 0;
105             segment_point_type const* sp = 0;
106 
107             bool b = str->apply(*p, *sp, *sp, *st);
108             int r = str->result(*st);
109 
110             boost::ignore_unused(r, b, str);
111         }
112     };
113 
114 
115 public :
BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)116     BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
117     {
118         checker::apply(&Strategy::template apply<Point, point_of_segment>,
119                        &Strategy::result);
120     }
121 #endif
122 };
123 
124 template <typename Point, typename Box, typename Strategy>
125 class WithinStrategyPointBox
126 {
127 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
128 
129     struct checker
130     {
131         template <typename ApplyMethod>
applyboost::geometry::concepts::WithinStrategyPointBox::checker132         static void apply(ApplyMethod)
133         {
134             typedef typename parameter_type_of
135                 <
136                     ApplyMethod, 0
137                 >::type point_type;
138             typedef typename parameter_type_of
139                 <
140                     ApplyMethod, 1
141                 >::type box_type;
142 
143             // CHECK: apply-arguments should fulfill point/box concept
144             BOOST_CONCEPT_ASSERT
145                 (
146                     (concepts::ConstPoint<point_type>)
147                 );
148 
149             BOOST_CONCEPT_ASSERT
150                 (
151                     (concepts::ConstBox<box_type>)
152                 );
153 
154             // CHECK: return types (apply: bool)
155             BOOST_MPL_ASSERT_MSG
156                 (
157                     (boost::is_same
158                         <
159                             bool,
160                             typename boost::function_types::result_type<ApplyMethod>::type
161                         >::type::value),
162                     WRONG_RETURN_TYPE
163                     , (bool)
164                 );
165 
166 
167             // CHECK: calling method apply
168             Strategy const* str = 0;
169             point_type const* p = 0;
170             box_type const* bx = 0;
171 
172             bool b = str->apply(*p, *bx);
173 
174             boost::ignore_unused(b, str);
175         }
176     };
177 
178 
179 public :
BOOST_CONCEPT_USAGE(WithinStrategyPointBox)180     BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
181     {
182         checker::apply(&Strategy::template apply<Point, Box>);
183     }
184 #endif
185 };
186 
187 template <typename Box1, typename Box2, typename Strategy>
188 class WithinStrategyBoxBox
189 {
190 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
191 
192     struct checker
193     {
194         template <typename ApplyMethod>
applyboost::geometry::concepts::WithinStrategyBoxBox::checker195         static void apply(ApplyMethod const&)
196         {
197             typedef typename parameter_type_of
198                 <
199                     ApplyMethod, 0
200                 >::type box_type1;
201             typedef typename parameter_type_of
202                 <
203                     ApplyMethod, 1
204                 >::type box_type2;
205 
206             // CHECK: apply-arguments should both fulfill box concept
207             BOOST_CONCEPT_ASSERT
208                 (
209                     (concepts::ConstBox<box_type1>)
210                 );
211 
212             BOOST_CONCEPT_ASSERT
213                 (
214                     (concepts::ConstBox<box_type2>)
215                 );
216 
217             // CHECK: return types (apply: bool)
218             BOOST_MPL_ASSERT_MSG
219                 (
220                     (boost::is_same
221                         <
222                             bool,
223                             typename boost::function_types::result_type<ApplyMethod>::type
224                         >::type::value),
225                     WRONG_RETURN_TYPE
226                     , (bool)
227                 );
228 
229 
230             // CHECK: calling method apply
231             Strategy const* str = 0;
232             box_type1 const* b1 = 0;
233             box_type2 const* b2 = 0;
234 
235             bool b = str->apply(*b1, *b2);
236 
237             boost::ignore_unused(b, str);
238         }
239     };
240 
241 
242 public :
BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)243     BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
244     {
245         checker::apply(&Strategy::template apply<Box1, Box2>);
246     }
247 #endif
248 };
249 
250 // So now: boost::geometry::concepts::within
251 namespace within
252 {
253 
254 #ifndef DOXYGEN_NO_DISPATCH
255 namespace dispatch
256 {
257 
258 template
259 <
260     typename Geometry1, typename Geometry2,
261     typename FirstTag, typename SecondTag, typename CastedTag,
262     typename Strategy
263 >
264 struct check_within
265 {};
266 
267 
268 template
269 <
270     typename Geometry1, typename Geometry2,
271     typename AnyTag,
272     typename Strategy
273 >
274 struct check_within<Geometry1, Geometry2, point_tag, AnyTag, areal_tag, Strategy>
275 {
276     BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Geometry1, Geometry2, Strategy>) );
277 };
278 
279 
280 template <typename Geometry1, typename Geometry2, typename Strategy>
281 struct check_within<Geometry1, Geometry2, point_tag, box_tag, areal_tag, Strategy>
282 {
283     BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Geometry1, Geometry2, Strategy>) );
284 };
285 
286 template <typename Geometry1, typename Geometry2, typename Strategy>
287 struct check_within<Geometry1, Geometry2, box_tag, box_tag, areal_tag, Strategy>
288 {
289     BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Geometry1, Geometry2, Strategy>) );
290 };
291 
292 
293 } // namespace dispatch
294 #endif
295 
296 
297 /*!
298 \brief Checks, in compile-time, the concept of any within-strategy
299 \ingroup concepts
300 */
301 template <typename Geometry1, typename Geometry2, typename Strategy>
check()302 inline void check()
303 {
304     dispatch::check_within
305         <
306             Geometry1,
307             Geometry2,
308             typename tag<Geometry1>::type,
309             typename tag<Geometry2>::type,
310             typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
311             Strategy
312         > c;
313     boost::ignore_unused(c);
314 }
315 
316 
317 }}}} // namespace boost::geometry::concepts::within
318 
319 
320 #endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
321