Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2014-2021, Oracle and/or its affiliates.
0004 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0005 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0006 
0007 // Licensed under the Boost Software License version 1.0.
0008 // http://www.boost.org/users/license.html
0009 
0010 #ifndef BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP
0011 #define BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP
0012 
0013 
0014 #include <type_traits>
0015 
0016 #include <boost/range/begin.hpp>
0017 #include <boost/range/end.hpp>
0018 
0019 #include <boost/geometry/core/exterior_ring.hpp>
0020 #include <boost/geometry/core/interior_rings.hpp>
0021 #include <boost/geometry/core/tags.hpp>
0022 
0023 #include <boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp>
0024 #include <boost/geometry/iterators/detail/segment_iterator/iterator_type.hpp>
0025 
0026 #include <boost/geometry/iterators/dispatch/segment_iterator.hpp>
0027 
0028 
0029 namespace boost { namespace geometry
0030 {
0031 
0032 
0033 #ifndef DOXYGEN_NO_DISPATCH
0034 namespace dispatch
0035 {
0036 
0037 
0038 // specializations for segments_begin
0039 
0040 
0041 template <typename Linestring>
0042 struct segments_begin<Linestring, linestring_tag>
0043 {
0044     typedef typename detail::segment_iterator::iterator_type
0045         <
0046             Linestring
0047         >::type return_type;
0048 
0049     static inline return_type apply(Linestring& linestring)
0050     {
0051         return return_type(linestring);
0052     }
0053 };
0054 
0055 
0056 template <typename Ring>
0057 struct segments_begin<Ring, ring_tag>
0058 {
0059     typedef typename detail::segment_iterator::iterator_type
0060         <
0061             Ring
0062         >::type return_type;
0063 
0064     static inline return_type apply(Ring& ring)
0065     {
0066         return return_type(ring);
0067     }
0068 };
0069 
0070 
0071 template <typename Polygon>
0072 struct segments_begin<Polygon, polygon_tag>
0073 {
0074     typedef typename detail::point_iterator::inner_range_type
0075         <
0076             Polygon
0077         >::type inner_range;
0078 
0079     typedef typename detail::segment_iterator::iterator_type
0080         <
0081             Polygon
0082         >::type return_type;
0083 
0084     static inline return_type apply(Polygon& polygon)
0085     {
0086         typedef typename return_type::second_iterator_type flatten_iterator;
0087 
0088         return return_type
0089             (segments_begin
0090                  <
0091                      inner_range
0092                  >::apply(geometry::exterior_ring(polygon)),
0093              segments_end
0094                  <
0095                      inner_range
0096                  >::apply(geometry::exterior_ring(polygon)),
0097              flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
0098                               boost::end(geometry::interior_rings(polygon))
0099                               ),
0100              flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
0101                               boost::end(geometry::interior_rings(polygon))
0102                               )
0103              );
0104     }
0105 };
0106 
0107 
0108 template <typename MultiLinestring>
0109 struct segments_begin<MultiLinestring, multi_linestring_tag>
0110 {
0111     typedef typename detail::segment_iterator::iterator_type
0112         <
0113             MultiLinestring
0114         >::type return_type;
0115 
0116     static inline return_type apply(MultiLinestring& multilinestring)
0117     {
0118         return return_type(boost::begin(multilinestring),
0119                            boost::end(multilinestring));
0120     }
0121 };
0122 
0123 
0124 template <typename MultiPolygon>
0125 struct segments_begin<MultiPolygon, multi_polygon_tag>
0126 {
0127     typedef typename detail::segment_iterator::iterator_type
0128         <
0129             MultiPolygon
0130         >::type return_type;
0131 
0132     static inline return_type apply(MultiPolygon& multipolygon)
0133     {
0134         return return_type(boost::begin(multipolygon),
0135                            boost::end(multipolygon));
0136     }
0137 };
0138 
0139 
0140 } // namespace dispatch
0141 #endif // DOXYGEN_NO_DISPATCH
0142 
0143 
0144 
0145 
0146 
0147 #ifndef DOXYGEN_NO_DISPATCH
0148 namespace dispatch
0149 {
0150 
0151 
0152 // specializations for segments_end
0153 
0154 
0155 template <typename Linestring>
0156 struct segments_end<Linestring, linestring_tag>
0157 {
0158     typedef typename detail::segment_iterator::iterator_type
0159         <
0160             Linestring
0161         >::type return_type;
0162 
0163     static inline return_type apply(Linestring& linestring)
0164     {
0165         return return_type(linestring, true);
0166     }
0167 };
0168 
0169 
0170 template <typename Ring>
0171 struct segments_end<Ring, ring_tag>
0172 {
0173     typedef typename detail::segment_iterator::iterator_type
0174         <
0175             Ring
0176         >::type return_type;
0177 
0178     static inline return_type apply(Ring& ring)
0179     {
0180         return return_type(ring, true);
0181     }
0182 };
0183 
0184 
0185 template <typename Polygon>
0186 struct segments_end<Polygon, polygon_tag>
0187 {
0188     typedef typename detail::point_iterator::inner_range_type
0189         <
0190             Polygon
0191         >::type inner_range;
0192 
0193     typedef typename detail::segment_iterator::iterator_type
0194         <
0195             Polygon
0196         >::type return_type;
0197 
0198     static inline return_type apply(Polygon& polygon)
0199     {
0200         typedef typename return_type::second_iterator_type flatten_iterator;
0201 
0202         return return_type
0203             (segments_end
0204                  <
0205                      inner_range
0206                  >::apply(geometry::exterior_ring(polygon)),
0207              flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
0208                               boost::end(geometry::interior_rings(polygon))
0209                               ),
0210              flatten_iterator( boost::end(geometry::interior_rings(polygon)) )
0211              );
0212     }
0213 };
0214 
0215 
0216 template <typename MultiLinestring>
0217 struct segments_end<MultiLinestring, multi_linestring_tag>
0218 {
0219     typedef typename detail::segment_iterator::iterator_type
0220         <
0221             MultiLinestring
0222         >::type return_type;
0223 
0224     static inline return_type apply(MultiLinestring& multilinestring)
0225     {
0226         return return_type(boost::end(multilinestring));
0227     }
0228 };
0229 
0230 
0231 template <typename MultiPolygon>
0232 struct segments_end<MultiPolygon, multi_polygon_tag>
0233 {
0234     typedef typename detail::segment_iterator::iterator_type
0235         <
0236             MultiPolygon
0237         >::type return_type;
0238 
0239     static inline return_type apply(MultiPolygon& multipolygon)
0240     {
0241         return return_type(boost::end(multipolygon));
0242     }
0243 };
0244 
0245 
0246 } // namespace dispatch
0247 #endif // DOXYGEN_NO_DISPATCH
0248 
0249 
0250 // MK:: need to add doc here
0251 template <typename Geometry>
0252 class segment_iterator
0253     : public detail::segment_iterator::iterator_type<Geometry>::type
0254 {
0255 private:
0256     typedef typename detail::segment_iterator::iterator_type
0257         <
0258             Geometry
0259         >::type base;
0260 
0261     inline base const* base_ptr() const
0262     {
0263         return this;
0264     }
0265 
0266     template <typename OtherGeometry> friend class segment_iterator;
0267 
0268     template <typename G>
0269     friend inline segment_iterator<G const> segments_begin(G const&);
0270 
0271     template <typename G>
0272     friend inline segment_iterator<G const> segments_end(G const&);
0273 
0274     inline segment_iterator(base const& base_it) : base(base_it) {}
0275 
0276 public:
0277     // The following typedef is needed for this iterator to be
0278     // bidirectional.
0279     // Normally we would not have to define this. However, due to the
0280     // fact that the value type of the iterator is not a reference,
0281     // the iterator_facade framework (used to define the base class of
0282     // this iterator) degrades automatically the iterator's category
0283     // to input iterator. With the following typedef we recover the
0284     // correct iterator category.
0285     typedef std::bidirectional_iterator_tag iterator_category;
0286 
0287     inline segment_iterator() = default;
0288 
0289     template
0290     <
0291         typename OtherGeometry,
0292         std::enable_if_t
0293             <
0294                 std::is_convertible
0295                     <
0296                         typename detail::segment_iterator::iterator_type<OtherGeometry>::type,
0297                         typename detail::segment_iterator::iterator_type<Geometry>::type
0298                     >::value,
0299                 int
0300             > = 0
0301     >
0302     inline segment_iterator(segment_iterator<OtherGeometry> const& other)
0303         : base(*other.base_ptr())
0304     {}
0305 
0306     inline segment_iterator& operator++() // prefix
0307     {
0308         base::operator++();
0309         return *this;
0310     }
0311 
0312     inline segment_iterator& operator--() // prefix
0313     {
0314         base::operator--();
0315         return *this;
0316     }
0317 
0318     inline segment_iterator operator++(int) // postfix
0319     {
0320         segment_iterator copy(*this);
0321         base::operator++();
0322         return copy;
0323     }
0324 
0325     inline segment_iterator operator--(int) // postfix
0326     {
0327         segment_iterator copy(*this);
0328         base::operator--();
0329         return copy;
0330     }
0331 };
0332 
0333 
0334 // MK:: need to add doc here
0335 template <typename Geometry>
0336 inline segment_iterator<Geometry const>
0337 segments_begin(Geometry const& geometry)
0338 {
0339     return dispatch::segments_begin<Geometry const>::apply(geometry);
0340 }
0341 
0342 
0343 // MK:: need to add doc here
0344 template <typename Geometry>
0345 inline segment_iterator<Geometry const>
0346 segments_end(Geometry const& geometry)
0347 {
0348     return dispatch::segments_end<Geometry const>::apply(geometry);
0349 }
0350 
0351 
0352 }} // namespace boost::geometry
0353 
0354 #endif // BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP