File indexing completed on 2025-12-15 09:50:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
0015 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
0016
0017 #include <type_traits>
0018
0019 #include <boost/geometry/algorithms/not_implemented.hpp>
0020
0021 #include <boost/geometry/core/assert.hpp>
0022 #include <boost/geometry/core/exterior_ring.hpp>
0023 #include <boost/geometry/core/interior_rings.hpp>
0024 #include <boost/geometry/core/tag.hpp>
0025 #include <boost/geometry/core/tags.hpp>
0026
0027 #include <boost/geometry/util/range.hpp>
0028 #include <boost/geometry/util/type_traits.hpp>
0029
0030 namespace boost { namespace geometry {
0031
0032 #ifndef DOXYGEN_NO_DETAIL
0033
0034 #ifndef DOXYGEN_NO_DISPATCH
0035 namespace detail_dispatch {
0036
0037 template
0038 <
0039 typename Geometry,
0040 typename Tag = geometry::tag_t<Geometry>,
0041 bool IsMulti = util::is_multi<Geometry>::value
0042 >
0043 struct sub_range : not_implemented<Tag>
0044 {};
0045
0046 template <typename Geometry, typename Tag>
0047 struct sub_range<Geometry, Tag, false>
0048 {
0049 typedef Geometry & return_type;
0050
0051 template <typename Id> static inline
0052 return_type apply(Geometry & geometry, Id const&)
0053 {
0054 return geometry;
0055 }
0056 };
0057
0058 template <typename Geometry>
0059 struct sub_range<Geometry, polygon_tag, false>
0060 {
0061 using return_type = geometry::ring_return_type_t<Geometry>;
0062
0063 template <typename Id> static inline
0064 return_type apply(Geometry & geometry, Id const& id)
0065 {
0066 if ( id.ring_index < 0 )
0067 {
0068 return geometry::exterior_ring(geometry);
0069 }
0070 else
0071 {
0072 using size_type = typename boost::range_size
0073 <
0074 typename geometry::interior_type<Geometry>::type
0075 >::type;
0076 size_type const ri = static_cast<size_type>(id.ring_index);
0077 return range::at(geometry::interior_rings(geometry), ri);
0078 }
0079 }
0080 };
0081
0082 template <typename Geometry, typename Tag>
0083 struct sub_range<Geometry, Tag, true>
0084 {
0085 typedef typename boost::range_value<Geometry>::type value_type;
0086 typedef std::conditional_t
0087 <
0088 std::is_const<Geometry>::value,
0089 typename std::add_const<value_type>::type,
0090 value_type
0091 > sub_type;
0092
0093 typedef detail_dispatch::sub_range<sub_type> sub_sub_range;
0094
0095
0096 typedef typename sub_sub_range::return_type return_type;
0097
0098 template <typename Id> static inline
0099 return_type apply(Geometry & geometry, Id const& id)
0100 {
0101 BOOST_GEOMETRY_ASSERT(0 <= id.multi_index);
0102 typedef typename boost::range_size<Geometry>::type size_type;
0103 size_type const mi = static_cast<size_type>(id.multi_index);
0104 return sub_sub_range::apply(range::at(geometry, mi), id);
0105 }
0106 };
0107
0108 }
0109 #endif
0110
0111 namespace detail {
0112
0113 template <typename Geometry>
0114 struct sub_range_return_type
0115 {
0116 typedef typename detail_dispatch::sub_range<Geometry>::return_type type;
0117 };
0118
0119
0120
0121 template <typename Geometry, typename Id> inline
0122 typename sub_range_return_type<Geometry>::type
0123 sub_range(Geometry & geometry, Id const& id)
0124 {
0125 return detail_dispatch::sub_range<Geometry>::apply(geometry, id);
0126 }
0127
0128 template <typename Geometry, typename Id> inline
0129 typename sub_range_return_type<Geometry const>::type
0130 sub_range(Geometry const& geometry, Id const& id)
0131 {
0132 return detail_dispatch::sub_range<Geometry const>::apply(geometry, id);
0133 }
0134
0135 }
0136 #endif
0137
0138 }}
0139
0140 #endif