within_concept.hpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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.
  6. // Modifications copyright (c) 2018 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 Strategy>
  31. class WithinStrategyPolygonal
  32. {
  33. #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
  34. // 1) must define state_type
  35. typedef typename Strategy::state_type state_type;
  36. struct checker
  37. {
  38. template <typename ApplyMethod, typename ResultMethod>
  39. static void apply(ApplyMethod const&, ResultMethod const& )
  40. {
  41. typedef typename parameter_type_of
  42. <
  43. ApplyMethod, 0
  44. >::type point_type;
  45. typedef typename parameter_type_of
  46. <
  47. ApplyMethod, 1
  48. >::type segment_point_type;
  49. // CHECK: apply-arguments should both fulfill point concept
  50. BOOST_CONCEPT_ASSERT
  51. (
  52. (concepts::ConstPoint<point_type>)
  53. );
  54. BOOST_CONCEPT_ASSERT
  55. (
  56. (concepts::ConstPoint<segment_point_type>)
  57. );
  58. // CHECK: return types (result: int, apply: bool)
  59. BOOST_MPL_ASSERT_MSG
  60. (
  61. (boost::is_same
  62. <
  63. bool, typename boost::function_types::result_type<ApplyMethod>::type
  64. >::type::value),
  65. WRONG_RETURN_TYPE_OF_APPLY
  66. , (bool)
  67. );
  68. BOOST_MPL_ASSERT_MSG
  69. (
  70. (boost::is_same
  71. <
  72. int, typename boost::function_types::result_type<ResultMethod>::type
  73. >::type::value),
  74. WRONG_RETURN_TYPE_OF_RESULT
  75. , (int)
  76. );
  77. // CHECK: calling method apply and result
  78. Strategy const* str = 0;
  79. state_type* st = 0;
  80. point_type const* p = 0;
  81. segment_point_type const* sp = 0;
  82. bool b = str->apply(*p, *sp, *sp, *st);
  83. int r = str->result(*st);
  84. boost::ignore_unused(r, b, str);
  85. }
  86. };
  87. public :
  88. BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
  89. {
  90. checker::apply(&Strategy::apply, &Strategy::result);
  91. }
  92. #endif
  93. };
  94. template <typename Point, typename Box, typename Strategy>
  95. class WithinStrategyPointBox
  96. {
  97. #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
  98. struct checker
  99. {
  100. template <typename ApplyMethod>
  101. static void apply(ApplyMethod const&)
  102. {
  103. typedef typename parameter_type_of
  104. <
  105. ApplyMethod, 0
  106. >::type point_type;
  107. typedef typename parameter_type_of
  108. <
  109. ApplyMethod, 1
  110. >::type box_type;
  111. // CHECK: apply-arguments should fulfill point/box concept
  112. BOOST_CONCEPT_ASSERT
  113. (
  114. (concepts::ConstPoint<point_type>)
  115. );
  116. BOOST_CONCEPT_ASSERT
  117. (
  118. (concepts::ConstBox<box_type>)
  119. );
  120. // CHECK: return types (apply: bool)
  121. BOOST_MPL_ASSERT_MSG
  122. (
  123. (boost::is_same
  124. <
  125. bool,
  126. typename boost::function_types::result_type<ApplyMethod>::type
  127. >::type::value),
  128. WRONG_RETURN_TYPE
  129. , (bool)
  130. );
  131. // CHECK: calling method apply
  132. Strategy const* str = 0;
  133. point_type const* p = 0;
  134. box_type const* bx = 0;
  135. bool b = str->apply(*p, *bx);
  136. boost::ignore_unused(b, str);
  137. }
  138. };
  139. public :
  140. BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
  141. {
  142. checker::apply(&Strategy::template apply<Point, Box>);
  143. }
  144. #endif
  145. };
  146. template <typename Strategy>
  147. class WithinStrategyBoxBox
  148. {
  149. #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
  150. struct checker
  151. {
  152. template <typename ApplyMethod>
  153. static void apply(ApplyMethod const&)
  154. {
  155. typedef typename parameter_type_of
  156. <
  157. ApplyMethod, 0
  158. >::type box_type1;
  159. typedef typename parameter_type_of
  160. <
  161. ApplyMethod, 1
  162. >::type box_type2;
  163. // CHECK: apply-arguments should both fulfill box concept
  164. BOOST_CONCEPT_ASSERT
  165. (
  166. (concepts::ConstBox<box_type1>)
  167. );
  168. BOOST_CONCEPT_ASSERT
  169. (
  170. (concepts::ConstBox<box_type2>)
  171. );
  172. // CHECK: return types (apply: bool)
  173. BOOST_MPL_ASSERT_MSG
  174. (
  175. (boost::is_same
  176. <
  177. bool,
  178. typename boost::function_types::result_type<ApplyMethod>::type
  179. >::type::value),
  180. WRONG_RETURN_TYPE
  181. , (bool)
  182. );
  183. // CHECK: calling method apply
  184. Strategy const* str = 0;
  185. box_type1 const* b1 = 0;
  186. box_type2 const* b2 = 0;
  187. bool b = str->apply(*b1, *b2);
  188. boost::ignore_unused(b, str);
  189. }
  190. };
  191. public :
  192. BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
  193. {
  194. checker::apply(&Strategy::apply);
  195. }
  196. #endif
  197. };
  198. // So now: boost::geometry::concepts::within
  199. namespace within
  200. {
  201. #ifndef DOXYGEN_NO_DISPATCH
  202. namespace dispatch
  203. {
  204. template
  205. <
  206. typename Geometry1, typename Geometry2,
  207. typename FirstTag, typename SecondTag, typename CastedTag,
  208. typename Strategy
  209. >
  210. struct check_within
  211. {};
  212. template
  213. <
  214. typename Geometry1, typename Geometry2,
  215. typename AnyTag,
  216. typename Strategy
  217. >
  218. struct check_within<Geometry1, Geometry2, point_tag, AnyTag, areal_tag, Strategy>
  219. {
  220. BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Strategy>) );
  221. };
  222. template <typename Geometry1, typename Geometry2, typename Strategy>
  223. struct check_within<Geometry1, Geometry2, point_tag, box_tag, areal_tag, Strategy>
  224. {
  225. BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Geometry1, Geometry2, Strategy>) );
  226. };
  227. template <typename Geometry1, typename Geometry2, typename Strategy>
  228. struct check_within<Geometry1, Geometry2, box_tag, box_tag, areal_tag, Strategy>
  229. {
  230. BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Strategy>) );
  231. };
  232. } // namespace dispatch
  233. #endif
  234. /*!
  235. \brief Checks, in compile-time, the concept of any within-strategy
  236. \ingroup concepts
  237. */
  238. template <typename Geometry1, typename Geometry2, typename Strategy>
  239. inline void check()
  240. {
  241. dispatch::check_within
  242. <
  243. Geometry1,
  244. Geometry2,
  245. typename tag<Geometry1>::type,
  246. typename tag<Geometry2>::type,
  247. typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
  248. Strategy
  249. > c;
  250. boost::ignore_unused(c);
  251. }
  252. }}}} // namespace boost::geometry::concepts::within
  253. #endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP