Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:21

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2014-2023, Oracle and/or its affiliates.
0004 
0005 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0006 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0007 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0008 
0009 // Licensed under the Boost Software License version 1.0.
0010 // http://www.boost.org/users/license.html
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 }} // namespace detail::num_segments
0061 #endif // DOXYGEN_NO_DETAIL
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 // the number of segments (1-dimensional faces) of the hypercube is
0080 // given by the formula: d * 2^(d-1), where d is the dimension of the
0081 // hypercube; see also:
0082 //            http://en.wikipedia.org/wiki/Hypercube
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 } // namespace dispatch
0135 #endif // DOXYGEN_NO_DISPATCH
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 } // namespace resolve_dynamic
0187 
0188 
0189 
0190 /*!
0191 \brief \brief_calc{number of segments}
0192 \ingroup num_segments
0193 \details \details_calc{num_segments, number of segments}.
0194 \tparam Geometry \tparam_geometry
0195 \param geometry \param_geometry
0196 \return \return_calc{number of segments}
0197 
0198 \qbk{[include reference/algorithms/num_segments.qbk]}
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 }} // namespace boost::geometry
0209 
0210 #endif // BOOST_GEOMETRY_ALGORITHMS_NUM_SEGMENTS_HPP