File indexing completed on 2025-01-18 09:36:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
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 }
0085
0086
0087
0088
0089
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
0099 typedef typename concepts::detail::relate_strategy_dispatch
0100 <
0101 Point, Polygonal, Strategy
0102 >::type strategy_type;
0103
0104
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
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
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
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
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
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
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
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
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
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
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
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
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 }
0358 #endif
0359
0360
0361
0362
0363
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 }}}}
0382
0383
0384 #endif