sub_range.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2013, 2014.
  4. // Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
  5. // Use, modification and distribution is subject to the Boost Software License,
  6. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  9. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
  10. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
  11. #include <boost/mpl/if.hpp>
  12. #include <boost/geometry/core/assert.hpp>
  13. #include <boost/geometry/util/range.hpp>
  14. namespace boost { namespace geometry {
  15. #ifndef DOXYGEN_NO_DETAIL
  16. #ifndef DOXYGEN_NO_DISPATCH
  17. namespace detail_dispatch {
  18. template <typename Geometry,
  19. typename Tag = typename geometry::tag<Geometry>::type,
  20. bool IsMulti = boost::is_base_of<multi_tag, Tag>::value>
  21. struct sub_range : not_implemented<Tag>
  22. {};
  23. template <typename Geometry, typename Tag>
  24. struct sub_range<Geometry, Tag, false>
  25. {
  26. typedef Geometry & return_type;
  27. template <typename Id> static inline
  28. return_type apply(Geometry & geometry, Id const&)
  29. {
  30. return geometry;
  31. }
  32. };
  33. template <typename Geometry>
  34. struct sub_range<Geometry, polygon_tag, false>
  35. {
  36. typedef typename geometry::ring_return_type<Geometry>::type return_type;
  37. template <typename Id> static inline
  38. return_type apply(Geometry & geometry, Id const& id)
  39. {
  40. if ( id.ring_index < 0 )
  41. {
  42. return geometry::exterior_ring(geometry);
  43. }
  44. else
  45. {
  46. typedef typename boost::range_size
  47. <
  48. typename geometry::interior_type<Geometry>::type
  49. >::type size_type;
  50. size_type const ri = static_cast<size_type>(id.ring_index);
  51. return range::at(geometry::interior_rings(geometry), ri);
  52. }
  53. }
  54. };
  55. template <typename Geometry, typename Tag>
  56. struct sub_range<Geometry, Tag, true>
  57. {
  58. typedef typename boost::range_value<Geometry>::type value_type;
  59. typedef typename boost::mpl::if_c
  60. <
  61. boost::is_const<Geometry>::value,
  62. typename boost::add_const<value_type>::type,
  63. value_type
  64. >::type sub_type;
  65. typedef detail_dispatch::sub_range<sub_type> sub_sub_range;
  66. // TODO: shouldn't it be return_type?
  67. typedef typename sub_sub_range::return_type return_type;
  68. template <typename Id> static inline
  69. return_type apply(Geometry & geometry, Id const& id)
  70. {
  71. BOOST_GEOMETRY_ASSERT(0 <= id.multi_index);
  72. typedef typename boost::range_size<Geometry>::type size_type;
  73. size_type const mi = static_cast<size_type>(id.multi_index);
  74. return sub_sub_range::apply(range::at(geometry, mi), id);
  75. }
  76. };
  77. } // namespace detail_dispatch
  78. #endif // DOXYGEN_NO_DISPATCH
  79. namespace detail {
  80. template <typename Geometry>
  81. struct sub_range_return_type
  82. {
  83. typedef typename detail_dispatch::sub_range<Geometry>::return_type type;
  84. };
  85. // This function also works for geometry::segment_identifier
  86. template <typename Geometry, typename Id> inline
  87. typename sub_range_return_type<Geometry>::type
  88. sub_range(Geometry & geometry, Id const& id)
  89. {
  90. return detail_dispatch::sub_range<Geometry>::apply(geometry, id);
  91. }
  92. template <typename Geometry, typename Id> inline
  93. typename sub_range_return_type<Geometry const>::type
  94. sub_range(Geometry const& geometry, Id const& id)
  95. {
  96. return detail_dispatch::sub_range<Geometry const>::apply(geometry, id);
  97. }
  98. } // namespace detail
  99. #endif // DOXYGEN_NO_DETAIL
  100. }} // namespace boost::geometry
  101. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP