1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
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
11 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
12 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
18 #ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
19 #define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
22 #include <type_traits>
24 #include <boost/concept_check.hpp>
25 #include <boost/core/ignore_unused.hpp>
26 #include <boost/function_types/result_type.hpp>
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>
33 #include <boost/geometry/geometries/concepts/box_concept.hpp>
34 #include <boost/geometry/geometries/concepts/point_concept.hpp>
36 #include <boost/geometry/strategies/detail.hpp>
38 #include <boost/geometry/util/parameter_type_of.hpp>
41 namespace boost { namespace geometry { namespace concepts
51 typename Point, typename Geometry, typename Strategy,
52 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
54 struct relate_strategy_dispatch
56 using type = decltype(std::declval<Strategy>().relate(
57 std::declval<Point>(), std::declval<Geometry>()));
60 template <typename Point, typename Geometry, typename Strategy>
61 struct relate_strategy_dispatch<Point, Geometry, Strategy, false>
63 using type = Strategy;
68 typename Point, typename Geometry, typename Strategy,
69 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
71 struct within_strategy_dispatch
73 using type = decltype(std::declval<Strategy>().within(
74 std::declval<Point>(), std::declval<Geometry>()));
77 template <typename Point, typename Geometry, typename Strategy>
78 struct within_strategy_dispatch<Point, Geometry, Strategy, false>
80 using type = Strategy;
88 \brief Checks strategy for within (point-in-polygon)
91 template <typename Point, typename Polygonal, typename Strategy>
92 class WithinStrategyPolygonal
94 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
96 typedef typename geometry::point_type<Polygonal>::type point_of_segment;
99 typedef typename concepts::detail::relate_strategy_dispatch
101 Point, Polygonal, Strategy
102 >::type strategy_type;
104 // 1) must define state_type
105 typedef typename strategy_type::state_type state_type;
109 template <typename ApplyMethod, typename ResultMethod>
110 static void apply(ApplyMethod, ResultMethod)
112 typedef typename parameter_type_of
116 typedef typename parameter_type_of
119 >::type segment_point_type;
121 // CHECK: apply-arguments should both fulfill point concept
124 (concepts::ConstPoint<point_type>)
129 (concepts::ConstPoint<segment_point_type>)
132 // CHECK: return types (result: int, apply: bool)
133 BOOST_GEOMETRY_STATIC_ASSERT
137 bool, typename boost::function_types::result_type<ApplyMethod>::type
139 "Wrong return type of apply().",
142 BOOST_GEOMETRY_STATIC_ASSERT
146 int, typename boost::function_types::result_type<ResultMethod>::type
148 "Wrong return type of result().",
153 // CHECK: calling method apply and result
154 strategy_type const* str = 0;
156 point_type const* p = 0;
157 segment_point_type const* sp = 0;
159 bool b = str->apply(*p, *sp, *sp, *st);
160 int r = str->result(*st);
162 boost::ignore_unused(r, b, str);
168 BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
170 checker::apply(&strategy_type::template apply<Point, point_of_segment>,
171 &strategy_type::result);
176 template <typename Point, typename Box, typename Strategy>
177 class WithinStrategyPointBox
179 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
182 typedef typename concepts::detail::within_strategy_dispatch
185 >::type strategy_type;
189 template <typename ApplyMethod>
190 static void apply(ApplyMethod)
192 typedef typename parameter_type_of
196 typedef typename parameter_type_of
201 // CHECK: apply-arguments should fulfill point/box concept
204 (concepts::ConstPoint<point_type>)
209 (concepts::ConstBox<box_type>)
212 // CHECK: return types (apply: bool)
213 BOOST_GEOMETRY_STATIC_ASSERT
218 typename boost::function_types::result_type<ApplyMethod>::type
220 "Wrong return type of apply().",
225 // CHECK: calling method apply
226 strategy_type const* str = 0;
227 point_type const* p = 0;
228 box_type const* bx = 0;
230 bool b = str->apply(*p, *bx);
232 boost::ignore_unused(b, str);
238 BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
240 checker::apply(&strategy_type::template apply<Point, Box>);
245 template <typename Box1, typename Box2, typename Strategy>
246 class WithinStrategyBoxBox
248 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
251 typedef typename concepts::detail::within_strategy_dispatch
254 >::type strategy_type;
258 template <typename ApplyMethod>
259 static void apply(ApplyMethod const&)
261 typedef typename parameter_type_of
265 typedef typename parameter_type_of
270 // CHECK: apply-arguments should both fulfill box concept
273 (concepts::ConstBox<box_type1>)
278 (concepts::ConstBox<box_type2>)
281 // CHECK: return types (apply: bool)
282 BOOST_GEOMETRY_STATIC_ASSERT
287 typename boost::function_types::result_type<ApplyMethod>::type
289 "Wrong return type of apply().",
294 // CHECK: calling method apply
295 strategy_type const* str = 0;
296 box_type1 const* b1 = 0;
297 box_type2 const* b2 = 0;
299 bool b = str->apply(*b1, *b2);
301 boost::ignore_unused(b, str);
307 BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
309 checker::apply(&strategy_type::template apply<Box1, Box2>);
314 // So now: boost::geometry::concepts::within
318 #ifndef DOXYGEN_NO_DISPATCH
324 typename Geometry1, typename Geometry2,
325 typename FirstTag, typename SecondTag, typename CastedTag,
334 typename Geometry1, typename Geometry2,
338 struct check_within<Geometry1, Geometry2, point_tag, AnyTag, areal_tag, Strategy>
340 BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Geometry1, Geometry2, Strategy>) );
344 template <typename Geometry1, typename Geometry2, typename Strategy>
345 struct check_within<Geometry1, Geometry2, point_tag, box_tag, areal_tag, Strategy>
347 BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Geometry1, Geometry2, Strategy>) );
350 template <typename Geometry1, typename Geometry2, typename Strategy>
351 struct check_within<Geometry1, Geometry2, box_tag, box_tag, areal_tag, Strategy>
353 BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Geometry1, Geometry2, Strategy>) );
357 } // namespace dispatch
362 \brief Checks, in compile-time, the concept of any within-strategy
365 template <typename Geometry1, typename Geometry2, typename Strategy>
368 dispatch::check_within
372 typename tag<Geometry1>::type,
373 typename tag<Geometry2>::type,
374 typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
377 boost::ignore_unused(c);
381 }}}} // namespace boost::geometry::concepts::within
384 #endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP