within_concept.hpp 7.7 KB

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