Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:44

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
0006 
0007 // This file was modified by Oracle on 2018-2020.
0008 // Modifications copyright (c) 2018-2020 Oracle and/or its affiliates.
0009 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0010 
0011 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0012 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0013 
0014 // Use, modification and distribution is subject to the Boost Software License,
0015 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0016 // http://www.boost.org/LICENSE_1_0.txt)
0017 
0018 #ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
0019 #define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
0020 
0021 
0022 #include <type_traits>
0023 
0024 #include <boost/concept_check.hpp>
0025 #include <boost/core/ignore_unused.hpp>
0026 #include <boost/function_types/result_type.hpp>
0027 
0028 #include <boost/geometry/core/static_assert.hpp>
0029 #include <boost/geometry/core/tag.hpp>
0030 #include <boost/geometry/core/tag_cast.hpp>
0031 #include <boost/geometry/core/tags.hpp>
0032 
0033 #include <boost/geometry/geometries/concepts/box_concept.hpp>
0034 #include <boost/geometry/geometries/concepts/point_concept.hpp>
0035 
0036 #include <boost/geometry/strategies/detail.hpp>
0037 
0038 #include <boost/geometry/util/parameter_type_of.hpp>
0039 
0040 
0041 namespace boost { namespace geometry { namespace concepts
0042 {
0043 
0044 
0045 namespace detail
0046 {
0047 
0048 
0049 template
0050 <
0051     typename Point, typename Geometry, typename Strategy,
0052     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0053 >
0054 struct relate_strategy_dispatch
0055 {
0056     using type = decltype(std::declval<Strategy>().relate(
0057                     std::declval<Point>(), std::declval<Geometry>()));
0058 };
0059 
0060 template <typename Point, typename Geometry, typename Strategy>
0061 struct relate_strategy_dispatch<Point, Geometry, Strategy, false>
0062 {
0063     using type = Strategy;
0064 };
0065 
0066 template
0067 <
0068     typename Point, typename Geometry, typename Strategy,
0069     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0070 >
0071 struct within_strategy_dispatch
0072 {
0073     using type = decltype(std::declval<Strategy>().within(
0074                     std::declval<Point>(), std::declval<Geometry>()));
0075 };
0076 
0077 template <typename Point, typename Geometry, typename Strategy>
0078 struct within_strategy_dispatch<Point, Geometry, Strategy, false>
0079 {
0080     using type = Strategy;
0081 };
0082 
0083 
0084 } // namespace detail
0085 
0086 
0087 /*!
0088 \brief Checks strategy for within (point-in-polygon)
0089 \ingroup within
0090 */
0091 template <typename Point, typename Polygonal, typename Strategy>
0092 class WithinStrategyPolygonal
0093 {
0094 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
0095 
0096     typedef typename geometry::point_type<Polygonal>::type point_of_segment;
0097 
0098     // 0)
0099     typedef typename concepts::detail::relate_strategy_dispatch
0100         <
0101             Point, Polygonal, Strategy
0102         >::type strategy_type;
0103 
0104     // 1) must define state_type
0105     typedef typename strategy_type::state_type state_type;
0106 
0107     struct checker
0108     {
0109         template <typename ApplyMethod, typename ResultMethod>
0110         static void apply(ApplyMethod, ResultMethod)
0111         {
0112             typedef typename parameter_type_of
0113                 <
0114                     ApplyMethod, 0
0115                 >::type point_type;
0116             typedef typename parameter_type_of
0117                 <
0118                     ApplyMethod, 1
0119                 >::type segment_point_type;
0120 
0121             // CHECK: apply-arguments should both fulfill point concept
0122             BOOST_CONCEPT_ASSERT
0123                 (
0124                     (concepts::ConstPoint<point_type>)
0125                 );
0126 
0127             BOOST_CONCEPT_ASSERT
0128                 (
0129                     (concepts::ConstPoint<segment_point_type>)
0130                 );
0131 
0132             // CHECK: return types (result: int, apply: bool)
0133             BOOST_GEOMETRY_STATIC_ASSERT
0134                 (
0135                     (std::is_same
0136                         <
0137                             bool, typename boost::function_types::result_type<ApplyMethod>::type
0138                         >::value),
0139                     "Wrong return type of apply().",
0140                     bool, ApplyMethod
0141                 );
0142             BOOST_GEOMETRY_STATIC_ASSERT
0143                 (
0144                     (std::is_same
0145                         <
0146                             int, typename boost::function_types::result_type<ResultMethod>::type
0147                         >::value),
0148                     "Wrong return type of result().",
0149                     int, ResultMethod
0150                 );
0151 
0152 
0153             // CHECK: calling method apply and result
0154             strategy_type const* str = 0;
0155             state_type* st = 0;
0156             point_type const* p = 0;
0157             segment_point_type const* sp = 0;
0158 
0159             bool b = str->apply(*p, *sp, *sp, *st);
0160             int r = str->result(*st);
0161 
0162             boost::ignore_unused(r, b, str);
0163         }
0164     };
0165 
0166 
0167 public :
0168     BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
0169     {
0170         checker::apply(&strategy_type::template apply<Point, point_of_segment>,
0171                        &strategy_type::result);
0172     }
0173 #endif
0174 };
0175 
0176 template <typename Point, typename Box, typename Strategy>
0177 class WithinStrategyPointBox
0178 {
0179 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
0180 
0181     // 0)
0182     typedef typename concepts::detail::within_strategy_dispatch
0183         <
0184             Point, Box, Strategy
0185         >::type strategy_type;
0186 
0187     struct checker
0188     {
0189         template <typename ApplyMethod>
0190         static void apply(ApplyMethod)
0191         {
0192             typedef typename parameter_type_of
0193                 <
0194                     ApplyMethod, 0
0195                 >::type point_type;
0196             typedef typename parameter_type_of
0197                 <
0198                     ApplyMethod, 1
0199                 >::type box_type;
0200 
0201             // CHECK: apply-arguments should fulfill point/box concept
0202             BOOST_CONCEPT_ASSERT
0203                 (
0204                     (concepts::ConstPoint<point_type>)
0205                 );
0206 
0207             BOOST_CONCEPT_ASSERT
0208                 (
0209                     (concepts::ConstBox<box_type>)
0210                 );
0211 
0212             // CHECK: return types (apply: bool)
0213             BOOST_GEOMETRY_STATIC_ASSERT
0214                 (
0215                     (std::is_same
0216                         <
0217                             bool,
0218                             typename boost::function_types::result_type<ApplyMethod>::type
0219                         >::value),
0220                     "Wrong return type of apply().",
0221                     bool, ApplyMethod
0222                 );
0223 
0224 
0225             // CHECK: calling method apply
0226             strategy_type const* str = 0;
0227             point_type const* p = 0;
0228             box_type const* bx = 0;
0229 
0230             bool b = str->apply(*p, *bx);
0231 
0232             boost::ignore_unused(b, str);
0233         }
0234     };
0235 
0236 
0237 public :
0238     BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
0239     {
0240         checker::apply(&strategy_type::template apply<Point, Box>);
0241     }
0242 #endif
0243 };
0244 
0245 template <typename Box1, typename Box2, typename Strategy>
0246 class WithinStrategyBoxBox
0247 {
0248 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
0249 
0250     // 0)
0251     typedef typename concepts::detail::within_strategy_dispatch
0252         <
0253             Box1, Box2, Strategy
0254         >::type strategy_type;
0255 
0256     struct checker
0257     {
0258         template <typename ApplyMethod>
0259         static void apply(ApplyMethod const&)
0260         {
0261             typedef typename parameter_type_of
0262                 <
0263                     ApplyMethod, 0
0264                 >::type box_type1;
0265             typedef typename parameter_type_of
0266                 <
0267                     ApplyMethod, 1
0268                 >::type box_type2;
0269 
0270             // CHECK: apply-arguments should both fulfill box concept
0271             BOOST_CONCEPT_ASSERT
0272                 (
0273                     (concepts::ConstBox<box_type1>)
0274                 );
0275 
0276             BOOST_CONCEPT_ASSERT
0277                 (
0278                     (concepts::ConstBox<box_type2>)
0279                 );
0280 
0281             // CHECK: return types (apply: bool)
0282             BOOST_GEOMETRY_STATIC_ASSERT
0283                 (
0284                     (std::is_same
0285                         <
0286                             bool,
0287                             typename boost::function_types::result_type<ApplyMethod>::type
0288                         >::value),
0289                     "Wrong return type of apply().",
0290                     bool, ApplyMethod
0291                 );
0292 
0293 
0294             // CHECK: calling method apply
0295             strategy_type const* str = 0;
0296             box_type1 const* b1 = 0;
0297             box_type2 const* b2 = 0;
0298 
0299             bool b = str->apply(*b1, *b2);
0300 
0301             boost::ignore_unused(b, str);
0302         }
0303     };
0304 
0305 
0306 public :
0307     BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
0308     {
0309         checker::apply(&strategy_type::template apply<Box1, Box2>);
0310     }
0311 #endif
0312 };
0313 
0314 // So now: boost::geometry::concepts::within
0315 namespace within
0316 {
0317 
0318 #ifndef DOXYGEN_NO_DISPATCH
0319 namespace dispatch
0320 {
0321 
0322 template
0323 <
0324     typename Geometry1, typename Geometry2,
0325     typename FirstTag, typename SecondTag, typename CastedTag,
0326     typename Strategy
0327 >
0328 struct check_within
0329 {};
0330 
0331 
0332 template
0333 <
0334     typename Geometry1, typename Geometry2,
0335     typename AnyTag,
0336     typename Strategy
0337 >
0338 struct check_within<Geometry1, Geometry2, point_tag, AnyTag, areal_tag, Strategy>
0339 {
0340     BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Geometry1, Geometry2, Strategy>) );
0341 };
0342 
0343 
0344 template <typename Geometry1, typename Geometry2, typename Strategy>
0345 struct check_within<Geometry1, Geometry2, point_tag, box_tag, areal_tag, Strategy>
0346 {
0347     BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Geometry1, Geometry2, Strategy>) );
0348 };
0349 
0350 template <typename Geometry1, typename Geometry2, typename Strategy>
0351 struct check_within<Geometry1, Geometry2, box_tag, box_tag, areal_tag, Strategy>
0352 {
0353     BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Geometry1, Geometry2, Strategy>) );
0354 };
0355 
0356 
0357 } // namespace dispatch
0358 #endif
0359 
0360 
0361 /*!
0362 \brief Checks, in compile-time, the concept of any within-strategy
0363 \ingroup concepts
0364 */
0365 template <typename Geometry1, typename Geometry2, typename Strategy>
0366 inline void check()
0367 {
0368     dispatch::check_within
0369         <
0370             Geometry1,
0371             Geometry2,
0372             typename tag<Geometry1>::type,
0373             typename tag<Geometry2>::type,
0374             typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
0375             Strategy
0376         > c;
0377     boost::ignore_unused(c);
0378 }
0379 
0380 
0381 }}}} // namespace boost::geometry::concepts::within
0382 
0383 
0384 #endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP