tupled.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Use, modification and distribution is subject to the Boost Software License,
  4. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
  7. #define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
  8. #include <string>
  9. #include <boost/tuple/tuple.hpp>
  10. #include <boost/geometry/strategies/side_info.hpp>
  11. #include <boost/geometry/util/select_calculation_type.hpp>
  12. #include <boost/geometry/util/select_most_precise.hpp>
  13. namespace boost { namespace geometry
  14. {
  15. namespace policies { namespace relate
  16. {
  17. // "tupled" to return intersection results together.
  18. // Now with two, with some meta-programming and derivations it can also be three (or more)
  19. template <typename Policy1, typename Policy2, typename CalculationType = void>
  20. struct segments_tupled
  21. {
  22. typedef boost::tuple
  23. <
  24. typename Policy1::return_type,
  25. typename Policy2::return_type
  26. > return_type;
  27. // Take segments of first policy, they should be equal
  28. typedef typename Policy1::segment_type1 segment_type1;
  29. typedef typename Policy1::segment_type2 segment_type2;
  30. typedef typename select_calculation_type
  31. <
  32. segment_type1,
  33. segment_type2,
  34. CalculationType
  35. >::type coordinate_type;
  36. // Get the same type, but at least a double
  37. typedef typename select_most_precise<coordinate_type, double>::type rtype;
  38. template <typename R>
  39. static inline return_type segments_intersect(side_info const& sides,
  40. R const& r,
  41. coordinate_type const& dx1, coordinate_type const& dy1,
  42. coordinate_type const& dx2, coordinate_type const& dy2,
  43. segment_type1 const& s1, segment_type2 const& s2)
  44. {
  45. return boost::make_tuple
  46. (
  47. Policy1::segments_intersect(sides, r,
  48. dx1, dy1, dx2, dy2, s1, s2),
  49. Policy2::segments_intersect(sides, r,
  50. dx1, dy1, dx2, dy2, s1, s2)
  51. );
  52. }
  53. static inline return_type collinear_touch(coordinate_type const& x,
  54. coordinate_type const& y, int arrival_a, int arrival_b)
  55. {
  56. return boost::make_tuple
  57. (
  58. Policy1::collinear_touch(x, y, arrival_a, arrival_b),
  59. Policy2::collinear_touch(x, y, arrival_a, arrival_b)
  60. );
  61. }
  62. template <typename S>
  63. static inline return_type collinear_interior_boundary_intersect(S const& segment,
  64. bool a_within_b,
  65. int arrival_a, int arrival_b, bool opposite)
  66. {
  67. return boost::make_tuple
  68. (
  69. Policy1::collinear_interior_boundary_intersect(segment, a_within_b, arrival_a, arrival_b, opposite),
  70. Policy2::collinear_interior_boundary_intersect(segment, a_within_b, arrival_a, arrival_b, opposite)
  71. );
  72. }
  73. static inline return_type collinear_a_in_b(segment_type1 const& segment,
  74. bool opposite)
  75. {
  76. return boost::make_tuple
  77. (
  78. Policy1::collinear_a_in_b(segment, opposite),
  79. Policy2::collinear_a_in_b(segment, opposite)
  80. );
  81. }
  82. static inline return_type collinear_b_in_a(segment_type2 const& segment,
  83. bool opposite)
  84. {
  85. return boost::make_tuple
  86. (
  87. Policy1::collinear_b_in_a(segment, opposite),
  88. Policy2::collinear_b_in_a(segment, opposite)
  89. );
  90. }
  91. static inline return_type collinear_overlaps(
  92. coordinate_type const& x1, coordinate_type const& y1,
  93. coordinate_type const& x2, coordinate_type const& y2,
  94. int arrival_a, int arrival_b, bool opposite)
  95. {
  96. return boost::make_tuple
  97. (
  98. Policy1::collinear_overlaps(x1, y1, x2, y2, arrival_a, arrival_b, opposite),
  99. Policy2::collinear_overlaps(x1, y1, x2, y2, arrival_a, arrival_b, opposite)
  100. );
  101. }
  102. static inline return_type segment_equal(segment_type1 const& s,
  103. bool opposite)
  104. {
  105. return boost::make_tuple
  106. (
  107. Policy1::segment_equal(s, opposite),
  108. Policy2::segment_equal(s, opposite)
  109. );
  110. }
  111. static inline return_type degenerate(segment_type1 const& segment,
  112. bool a_degenerate)
  113. {
  114. return boost::make_tuple
  115. (
  116. Policy1::degenerate(segment, a_degenerate),
  117. Policy2::degenerate(segment, a_degenerate)
  118. );
  119. }
  120. static inline return_type disjoint()
  121. {
  122. return boost::make_tuple
  123. (
  124. Policy1::disjoint(),
  125. Policy2::disjoint()
  126. );
  127. }
  128. static inline return_type error(std::string const& msg)
  129. {
  130. return boost::make_tuple
  131. (
  132. Policy1::error(msg),
  133. Policy2::error(msg)
  134. );
  135. }
  136. static inline return_type collinear_disjoint()
  137. {
  138. return boost::make_tuple
  139. (
  140. Policy1::collinear_disjoint(),
  141. Policy2::collinear_disjoint()
  142. );
  143. }
  144. };
  145. }} // namespace policies::relate
  146. }} // namespace boost::geometry
  147. #endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_TUPLED_HPP