File indexing completed on 2025-01-18 09:35:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP
0013 #define BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP
0014
0015 #include <cstddef>
0016
0017 #include <boost/range/size.hpp>
0018 #include <boost/range/value_type.hpp>
0019
0020 #include <boost/geometry/algorithms/detail/counting.hpp>
0021 #include <boost/geometry/algorithms/detail/visit.hpp>
0022 #include <boost/geometry/algorithms/not_implemented.hpp>
0023
0024 #include <boost/geometry/core/closure.hpp>
0025 #include <boost/geometry/core/tag.hpp>
0026 #include <boost/geometry/core/tags.hpp>
0027 #include <boost/geometry/core/visit.hpp>
0028
0029 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
0030 #include <boost/geometry/geometries/concepts/check.hpp>
0031
0032 namespace boost { namespace geometry
0033 {
0034
0035 #ifndef DOXYGEN_NO_DETAIL
0036 namespace detail { namespace num_segments
0037 {
0038
0039
0040 struct range_count
0041 {
0042 template <typename Range>
0043 static inline std::size_t apply(Range const& range)
0044 {
0045 std::size_t n = boost::size(range);
0046 if ( n <= 1 )
0047 {
0048 return 0;
0049 }
0050
0051 return
0052 geometry::closure<Range>::value == open
0053 ?
0054 n
0055 :
0056 static_cast<std::size_t>(n - 1);
0057 }
0058 };
0059
0060 }}
0061 #endif
0062
0063
0064
0065 #ifndef DOXYGEN_NO_DISPATCH
0066 namespace dispatch
0067 {
0068
0069 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
0070 struct num_segments
0071 : not_implemented<Tag>
0072 {};
0073
0074 template <typename Geometry>
0075 struct num_segments<Geometry, point_tag>
0076 : detail::counting::other_count<0>
0077 {};
0078
0079
0080
0081
0082
0083 template <typename Geometry>
0084 struct num_segments<Geometry, box_tag>
0085 : detail::counting::other_count
0086 <
0087 geometry::dimension<Geometry>::value
0088 * (1 << (geometry::dimension<Geometry>::value - 1))
0089 >
0090 {};
0091
0092 template <typename Geometry>
0093 struct num_segments<Geometry, segment_tag>
0094 : detail::counting::other_count<1>
0095 {};
0096
0097 template <typename Geometry>
0098 struct num_segments<Geometry, linestring_tag>
0099 : detail::num_segments::range_count
0100 {};
0101
0102 template <typename Geometry>
0103 struct num_segments<Geometry, ring_tag>
0104 : detail::num_segments::range_count
0105 {};
0106
0107 template <typename Geometry>
0108 struct num_segments<Geometry, polygon_tag>
0109 : detail::counting::polygon_count<detail::num_segments::range_count>
0110 {};
0111
0112 template <typename Geometry>
0113 struct num_segments<Geometry, multi_point_tag>
0114 : detail::counting::other_count<0>
0115 {};
0116
0117 template <typename Geometry>
0118 struct num_segments<Geometry, multi_linestring_tag>
0119 : detail::counting::multi_count
0120 <
0121 num_segments< typename boost::range_value<Geometry>::type>
0122 >
0123 {};
0124
0125 template <typename Geometry>
0126 struct num_segments<Geometry, multi_polygon_tag>
0127 : detail::counting::multi_count
0128 <
0129 num_segments< typename boost::range_value<Geometry>::type>
0130 >
0131 {};
0132
0133
0134 }
0135 #endif
0136
0137
0138
0139 namespace resolve_dynamic
0140 {
0141
0142
0143 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
0144 struct num_segments
0145 {
0146 static inline std::size_t apply(Geometry const& geometry)
0147 {
0148 concepts::check<Geometry const>();
0149
0150 return dispatch::num_segments<Geometry>::apply(geometry);
0151 }
0152 };
0153
0154
0155 template <typename Geometry>
0156 struct num_segments<Geometry, dynamic_geometry_tag>
0157 {
0158 static inline std::size_t apply(Geometry const& geometry)
0159 {
0160 std::size_t result = 0;
0161 traits::visit<Geometry>::apply([&](auto const& g)
0162 {
0163 result = num_segments<util::remove_cref_t<decltype(g)>>::apply(g);
0164 }, geometry);
0165 return result;
0166 }
0167 };
0168
0169
0170 template <typename Geometry>
0171 struct num_segments<Geometry, geometry_collection_tag>
0172 {
0173 static inline std::size_t apply(Geometry const& geometry)
0174 {
0175 std::size_t result = 0;
0176 detail::visit_breadth_first([&](auto const& g)
0177 {
0178 result += num_segments<util::remove_cref_t<decltype(g)>>::apply(g);
0179 return true;
0180 }, geometry);
0181 return result;
0182 }
0183 };
0184
0185
0186 }
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200 template <typename Geometry>
0201 inline std::size_t num_segments(Geometry const& geometry)
0202 {
0203 return resolve_dynamic::num_segments<Geometry>::apply(geometry);
0204 }
0205
0206
0207
0208 }}
0209
0210 #endif