123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- // Boost.Geometry (aka GGL, Generic Geometry Library)
- // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
- // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
- // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
- // This file was modified by Oracle on 2018-2020.
- // Modifications copyright (c) 2018-2020 Oracle and/or its affiliates.
- // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
- // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
- // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
- // Use, modification and distribution is subject to the Boost Software License,
- // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
- #define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
- #include <type_traits>
- #include <boost/concept_check.hpp>
- #include <boost/core/ignore_unused.hpp>
- #include <boost/function_types/result_type.hpp>
- #include <boost/geometry/core/static_assert.hpp>
- #include <boost/geometry/core/tag.hpp>
- #include <boost/geometry/core/tag_cast.hpp>
- #include <boost/geometry/core/tags.hpp>
- #include <boost/geometry/geometries/concepts/box_concept.hpp>
- #include <boost/geometry/geometries/concepts/point_concept.hpp>
- #include <boost/geometry/strategies/detail.hpp>
- #include <boost/geometry/util/parameter_type_of.hpp>
- namespace boost { namespace geometry { namespace concepts
- {
- namespace detail
- {
- template
- <
- typename Point, typename Geometry, typename Strategy,
- bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
- >
- struct relate_strategy_dispatch
- {
- using type = decltype(std::declval<Strategy>().relate(
- std::declval<Point>(), std::declval<Geometry>()));
- };
- template <typename Point, typename Geometry, typename Strategy>
- struct relate_strategy_dispatch<Point, Geometry, Strategy, false>
- {
- using type = Strategy;
- };
- template
- <
- typename Point, typename Geometry, typename Strategy,
- bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
- >
- struct within_strategy_dispatch
- {
- using type = decltype(std::declval<Strategy>().within(
- std::declval<Point>(), std::declval<Geometry>()));
- };
- template <typename Point, typename Geometry, typename Strategy>
- struct within_strategy_dispatch<Point, Geometry, Strategy, false>
- {
- using type = Strategy;
- };
- } // namespace detail
- /*!
- \brief Checks strategy for within (point-in-polygon)
- \ingroup within
- */
- template <typename Point, typename Polygonal, typename Strategy>
- class WithinStrategyPolygonal
- {
- #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
- typedef typename geometry::point_type<Polygonal>::type point_of_segment;
- // 0)
- typedef typename concepts::detail::relate_strategy_dispatch
- <
- Point, Polygonal, Strategy
- >::type strategy_type;
- // 1) must define state_type
- typedef typename strategy_type::state_type state_type;
- struct checker
- {
- template <typename ApplyMethod, typename ResultMethod>
- static void apply(ApplyMethod, ResultMethod)
- {
- typedef typename parameter_type_of
- <
- ApplyMethod, 0
- >::type point_type;
- typedef typename parameter_type_of
- <
- ApplyMethod, 1
- >::type segment_point_type;
- // CHECK: apply-arguments should both fulfill point concept
- BOOST_CONCEPT_ASSERT
- (
- (concepts::ConstPoint<point_type>)
- );
- BOOST_CONCEPT_ASSERT
- (
- (concepts::ConstPoint<segment_point_type>)
- );
- // CHECK: return types (result: int, apply: bool)
- BOOST_GEOMETRY_STATIC_ASSERT
- (
- (std::is_same
- <
- bool, typename boost::function_types::result_type<ApplyMethod>::type
- >::value),
- "Wrong return type of apply().",
- bool, ApplyMethod
- );
- BOOST_GEOMETRY_STATIC_ASSERT
- (
- (std::is_same
- <
- int, typename boost::function_types::result_type<ResultMethod>::type
- >::value),
- "Wrong return type of result().",
- int, ResultMethod
- );
- // CHECK: calling method apply and result
- strategy_type const* str = 0;
- state_type* st = 0;
- point_type const* p = 0;
- segment_point_type const* sp = 0;
- bool b = str->apply(*p, *sp, *sp, *st);
- int r = str->result(*st);
- boost::ignore_unused(r, b, str);
- }
- };
- public :
- BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
- {
- checker::apply(&strategy_type::template apply<Point, point_of_segment>,
- &strategy_type::result);
- }
- #endif
- };
- template <typename Point, typename Box, typename Strategy>
- class WithinStrategyPointBox
- {
- #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
- // 0)
- typedef typename concepts::detail::within_strategy_dispatch
- <
- Point, Box, Strategy
- >::type strategy_type;
- struct checker
- {
- template <typename ApplyMethod>
- static void apply(ApplyMethod)
- {
- typedef typename parameter_type_of
- <
- ApplyMethod, 0
- >::type point_type;
- typedef typename parameter_type_of
- <
- ApplyMethod, 1
- >::type box_type;
- // CHECK: apply-arguments should fulfill point/box concept
- BOOST_CONCEPT_ASSERT
- (
- (concepts::ConstPoint<point_type>)
- );
- BOOST_CONCEPT_ASSERT
- (
- (concepts::ConstBox<box_type>)
- );
- // CHECK: return types (apply: bool)
- BOOST_GEOMETRY_STATIC_ASSERT
- (
- (std::is_same
- <
- bool,
- typename boost::function_types::result_type<ApplyMethod>::type
- >::value),
- "Wrong return type of apply().",
- bool, ApplyMethod
- );
- // CHECK: calling method apply
- strategy_type const* str = 0;
- point_type const* p = 0;
- box_type const* bx = 0;
- bool b = str->apply(*p, *bx);
- boost::ignore_unused(b, str);
- }
- };
- public :
- BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
- {
- checker::apply(&strategy_type::template apply<Point, Box>);
- }
- #endif
- };
- template <typename Box1, typename Box2, typename Strategy>
- class WithinStrategyBoxBox
- {
- #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
- // 0)
- typedef typename concepts::detail::within_strategy_dispatch
- <
- Box1, Box2, Strategy
- >::type strategy_type;
- struct checker
- {
- template <typename ApplyMethod>
- static void apply(ApplyMethod const&)
- {
- typedef typename parameter_type_of
- <
- ApplyMethod, 0
- >::type box_type1;
- typedef typename parameter_type_of
- <
- ApplyMethod, 1
- >::type box_type2;
- // CHECK: apply-arguments should both fulfill box concept
- BOOST_CONCEPT_ASSERT
- (
- (concepts::ConstBox<box_type1>)
- );
- BOOST_CONCEPT_ASSERT
- (
- (concepts::ConstBox<box_type2>)
- );
- // CHECK: return types (apply: bool)
- BOOST_GEOMETRY_STATIC_ASSERT
- (
- (std::is_same
- <
- bool,
- typename boost::function_types::result_type<ApplyMethod>::type
- >::value),
- "Wrong return type of apply().",
- bool, ApplyMethod
- );
- // CHECK: calling method apply
- strategy_type const* str = 0;
- box_type1 const* b1 = 0;
- box_type2 const* b2 = 0;
- bool b = str->apply(*b1, *b2);
- boost::ignore_unused(b, str);
- }
- };
- public :
- BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
- {
- checker::apply(&strategy_type::template apply<Box1, Box2>);
- }
- #endif
- };
- // So now: boost::geometry::concepts::within
- namespace within
- {
- #ifndef DOXYGEN_NO_DISPATCH
- namespace dispatch
- {
- template
- <
- typename Geometry1, typename Geometry2,
- typename FirstTag, typename SecondTag, typename CastedTag,
- typename Strategy
- >
- struct check_within
- {};
- template
- <
- typename Geometry1, typename Geometry2,
- typename AnyTag,
- typename Strategy
- >
- struct check_within<Geometry1, Geometry2, point_tag, AnyTag, areal_tag, Strategy>
- {
- BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Geometry1, Geometry2, Strategy>) );
- };
- template <typename Geometry1, typename Geometry2, typename Strategy>
- struct check_within<Geometry1, Geometry2, point_tag, box_tag, areal_tag, Strategy>
- {
- BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Geometry1, Geometry2, Strategy>) );
- };
- template <typename Geometry1, typename Geometry2, typename Strategy>
- struct check_within<Geometry1, Geometry2, box_tag, box_tag, areal_tag, Strategy>
- {
- BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Geometry1, Geometry2, Strategy>) );
- };
- } // namespace dispatch
- #endif
- /*!
- \brief Checks, in compile-time, the concept of any within-strategy
- \ingroup concepts
- */
- template <typename Geometry1, typename Geometry2, typename Strategy>
- inline void check()
- {
- dispatch::check_within
- <
- Geometry1,
- Geometry2,
- typename tag<Geometry1>::type,
- typename tag<Geometry2>::type,
- typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
- Strategy
- > c;
- boost::ignore_unused(c);
- }
- }}}} // namespace boost::geometry::concepts::within
- #endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
|