sub_range.hpp 4.0 KB

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