within_concept.hpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // This file was modified by Oracle on 2018, 2019.
  6. // Modifications copyright (c) 2018, 2019 Oracle and/or its affiliates.
  7. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  8. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  9. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  10. // Use, modification and distribution is subject to the Boost Software License,
  11. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. #ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
  14. #define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
  15. #include <boost/concept_check.hpp>
  16. #include <boost/core/ignore_unused.hpp>
  17. #include <boost/function_types/result_type.hpp>
  18. #include <boost/geometry/core/tag.hpp>
  19. #include <boost/geometry/core/tag_cast.hpp>
  20. #include <boost/geometry/core/tags.hpp>
  21. #include <boost/geometry/geometries/concepts/box_concept.hpp>
  22. #include <boost/geometry/geometries/concepts/point_concept.hpp>
  23. #include <boost/geometry/util/parameter_type_of.hpp>
  24. namespace boost { namespace geometry { namespace concepts
  25. {
  26. /*!
  27. \brief Checks strategy for within (point-in-polygon)
  28. \ingroup within
  29. */
  30. template <typename Point, typename Polygonal, typename Strategy>
  31. class WithinStrategyPolygonal
  32. {
  33. #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
  34. typedef typename geometry::point_type<Polygonal>::type point_of_segment;
  35. // 1) must define state_type
  36. typedef typename Strategy::state_type state_type;
  37. struct checker
  38. {
  39. template <typename ApplyMethod, typename ResultMethod>
  40. static void apply(ApplyMethod, ResultMethod)
  41. {
  42. typedef typename parameter_type_of
  43. <
  44. ApplyMethod, 0
  45. >::type point_type;
  46. typedef typename parameter_type_of
  47. <
  48. ApplyMethod, 1
  49. >::type segment_point_type;
  50. // CHECK: apply-arguments should both fulfill point concept
  51. BOOST_CONCEPT_ASSERT
  52. (
  53. (concepts::ConstPoint<point_type>)
  54. );
  55. BOOST_CONCEPT_ASSERT
  56. (
  57. (concepts::ConstPoint<segment_point_type>)
  58. );
  59. // CHECK: return types (result: int, apply: bool)
  60. BOOST_MPL_ASSERT_MSG
  61. (
  62. (boost::is_same
  63. <
  64. bool, typename boost::function_types::result_type<ApplyMethod>::type
  65. >::type::value),
  66. WRONG_RETURN_TYPE_OF_APPLY
  67. , (bool)
  68. );
  69. BOOST_MPL_ASSERT_MSG
  70. (
  71. (boost::is_same
  72. <
  73. int, typename boost::function_types::result_type<ResultMethod>::type
  74. >::type::value),
  75. WRONG_RETURN_TYPE_OF_RESULT
  76. , (int)
  77. );
  78. // CHECK: calling method apply and result
  79. Strategy const* str = 0;
  80. state_type* st = 0;
  81. point_type const* p = 0;
  82. segment_point_type const* sp = 0;
  83. bool b = str->apply(*p, *sp, *sp, *st);
  84. int r = str->result(*st);
  85. boost::ignore_unused(r, b, str);
  86. }
  87. };
  88. public :
  89. BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
  90. {
  91. checker::apply(&Strategy::template apply<Point, point_of_segment>,
  92. &Strategy::result);
  93. }
  94. #endif
  95. };
  96. template <typename Point, typename Box, typename Strategy>
  97. class WithinStrategyPointBox
  98. {
  99. #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
  100. struct checker
  101. {
  102. template <typename ApplyMethod>
  103. static void apply(ApplyMethod)
  104. {
  105. typedef typename parameter_type_of
  106. <
  107. ApplyMethod, 0
  108. >::type point_type;
  109. typedef typename parameter_type_of
  110. <
  111. ApplyMethod, 1
  112. >::type box_type;
  113. // CHECK: apply-arguments should fulfill point/box concept
  114. BOOST_CONCEPT_ASSERT
  115. (
  116. (concepts::ConstPoint<point_type>)
  117. );
  118. BOOST_CONCEPT_ASSERT
  119. (
  120. (concepts::ConstBox<box_type>)
  121. );
  122. // CHECK: return types (apply: bool)
  123. BOOST_MPL_ASSERT_MSG
  124. (
  125. (boost::is_same
  126. <
  127. bool,
  128. typename boost::function_types::result_type<ApplyMethod>::type
  129. >::type::value),
  130. WRONG_RETURN_TYPE
  131. , (bool)
  132. );
  133. // CHECK: calling method apply
  134. Strategy const* str = 0;
  135. point_type const* p = 0;
  136. box_type const* bx = 0;
  137. bool b = str->apply(*p, *bx);
  138. boost::ignore_unused(b, str);
  139. }
  140. };
  141. public :
  142. BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
  143. {
  144. checker::apply(&Strategy::template apply<Point, Box>);
  145. }
  146. #endif
  147. };
  148. template <typename Box1, typename Box2, typename Strategy>
  149. class WithinStrategyBoxBox
  150. {
  151. #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
  152. struct checker
  153. {
  154. template <typename ApplyMethod>
  155. static void apply(ApplyMethod const&)
  156. {
  157. typedef typename parameter_type_of
  158. <
  159. ApplyMethod, 0
  160. >::type box_type1;
  161. typedef typename parameter_type_of
  162. <
  163. ApplyMethod, 1
  164. >::type box_type2;
  165. // CHECK: apply-arguments should both fulfill box concept
  166. BOOST_CONCEPT_ASSERT
  167. (
  168. (concepts::ConstBox<box_type1>)
  169. );
  170. BOOST_CONCEPT_ASSERT
  171. (
  172. (concepts::ConstBox<box_type2>)
  173. );
  174. // CHECK: return types (apply: bool)
  175. BOOST_MPL_ASSERT_MSG
  176. (
  177. (boost::is_same
  178. <
  179. bool,
  180. typename boost::function_types::result_type<ApplyMethod>::type
  181. >::type::value),
  182. WRONG_RETURN_TYPE
  183. , (bool)
  184. );
  185. // CHECK: calling method apply
  186. Strategy const* str = 0;
  187. box_type1 const* b1 = 0;
  188. box_type2 const* b2 = 0;
  189. bool b = str->apply(*b1, *b2);
  190. boost::ignore_unused(b, str);
  191. }
  192. };
  193. public :
  194. BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
  195. {
  196. checker::apply(&Strategy::template apply<Box1, Box2>);
  197. }
  198. #endif
  199. };
  200. // So now: boost::geometry::concepts::within
  201. namespace within
  202. {
  203. #ifndef DOXYGEN_NO_DISPATCH
  204. namespace dispatch
  205. {
  206. template
  207. <
  208. typename Geometry1, typename Geometry2,
  209. typename FirstTag, typename SecondTag, typename CastedTag,
  210. typename Strategy
  211. >
  212. struct check_within
  213. {};
  214. template
  215. <
  216. typename Geometry1, typename Geometry2,
  217. typename AnyTag,
  218. typename Strategy
  219. >
  220. struct check_within<Geometry1, Geometry2, point_tag, AnyTag, areal_tag, Strategy>
  221. {
  222. BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Geometry1, Geometry2, Strategy>) );
  223. };
  224. template <typename Geometry1, typename Geometry2, typename Strategy>
  225. struct check_within<Geometry1, Geometry2, point_tag, box_tag, areal_tag, Strategy>
  226. {
  227. BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Geometry1, Geometry2, Strategy>) );
  228. };
  229. template <typename Geometry1, typename Geometry2, typename Strategy>
  230. struct check_within<Geometry1, Geometry2, box_tag, box_tag, areal_tag, Strategy>
  231. {
  232. BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Geometry1, Geometry2, Strategy>) );
  233. };
  234. } // namespace dispatch
  235. #endif
  236. /*!
  237. \brief Checks, in compile-time, the concept of any within-strategy
  238. \ingroup concepts
  239. */
  240. template <typename Geometry1, typename Geometry2, typename Strategy>
  241. inline void check()
  242. {
  243. dispatch::check_within
  244. <
  245. Geometry1,
  246. Geometry2,
  247. typename tag<Geometry1>::type,
  248. typename tag<Geometry2>::type,
  249. typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
  250. Strategy
  251. > c;
  252. boost::ignore_unused(c);
  253. }
  254. }}}} // namespace boost::geometry::concepts::within
  255. #endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP