// Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2014, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html #ifndef BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP #define BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP #include #include #include #include #include #include #include #include #include namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { // specializations for segments_begin template struct segments_begin { typedef typename detail::segment_iterator::iterator_type < Linestring >::type return_type; static inline return_type apply(Linestring& linestring) { return return_type(linestring); } }; template struct segments_begin { typedef typename detail::segment_iterator::iterator_type < Ring >::type return_type; static inline return_type apply(Ring& ring) { return return_type(ring); } }; template struct segments_begin { typedef typename detail::point_iterator::inner_range_type < Polygon >::type inner_range; typedef typename detail::segment_iterator::iterator_type < Polygon >::type return_type; static inline return_type apply(Polygon& polygon) { typedef typename return_type::second_iterator_type flatten_iterator; return return_type (segments_begin < inner_range >::apply(geometry::exterior_ring(polygon)), segments_end < inner_range >::apply(geometry::exterior_ring(polygon)), flatten_iterator(boost::begin(geometry::interior_rings(polygon)), boost::end(geometry::interior_rings(polygon)) ), flatten_iterator(boost::begin(geometry::interior_rings(polygon)), boost::end(geometry::interior_rings(polygon)) ) ); } }; template struct segments_begin { typedef typename detail::segment_iterator::iterator_type < MultiLinestring >::type return_type; static inline return_type apply(MultiLinestring& multilinestring) { return return_type(boost::begin(multilinestring), boost::end(multilinestring)); } }; template struct segments_begin { typedef typename detail::segment_iterator::iterator_type < MultiPolygon >::type return_type; static inline return_type apply(MultiPolygon& multipolygon) { return return_type(boost::begin(multipolygon), boost::end(multipolygon)); } }; } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { // specializations for segments_end template struct segments_end { typedef typename detail::segment_iterator::iterator_type < Linestring >::type return_type; static inline return_type apply(Linestring& linestring) { return return_type(linestring, true); } }; template struct segments_end { typedef typename detail::segment_iterator::iterator_type < Ring >::type return_type; static inline return_type apply(Ring& ring) { return return_type(ring, true); } }; template struct segments_end { typedef typename detail::point_iterator::inner_range_type < Polygon >::type inner_range; typedef typename detail::segment_iterator::iterator_type < Polygon >::type return_type; static inline return_type apply(Polygon& polygon) { typedef typename return_type::second_iterator_type flatten_iterator; return return_type (segments_end < inner_range >::apply(geometry::exterior_ring(polygon)), flatten_iterator(boost::begin(geometry::interior_rings(polygon)), boost::end(geometry::interior_rings(polygon)) ), flatten_iterator( boost::end(geometry::interior_rings(polygon)) ) ); } }; template struct segments_end { typedef typename detail::segment_iterator::iterator_type < MultiLinestring >::type return_type; static inline return_type apply(MultiLinestring& multilinestring) { return return_type(boost::end(multilinestring)); } }; template struct segments_end { typedef typename detail::segment_iterator::iterator_type < MultiPolygon >::type return_type; static inline return_type apply(MultiPolygon& multipolygon) { return return_type(boost::end(multipolygon)); } }; } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH // MK:: need to add doc here template class segment_iterator : public detail::segment_iterator::iterator_type::type { private: typedef typename detail::segment_iterator::iterator_type < Geometry >::type base; inline base const* base_ptr() const { return this; } template friend class segment_iterator; template friend inline segment_iterator segments_begin(G const&); template friend inline segment_iterator segments_end(G const&); inline segment_iterator(base const& base_it) : base(base_it) {} public: // The following typedef is needed for this iterator to be // bidirectional. // Normally we would not have to define this. However, due to the // fact that the value type of the iterator is not a reference, // the iterator_facade framework (used to define the base class of // this iterator) degrades automatically the iterator's category // to input iterator. With the following typedef we recover the // correct iterator category. typedef std::bidirectional_iterator_tag iterator_category; inline segment_iterator() {} template inline segment_iterator(segment_iterator const& other) : base(*other.base_ptr()) { static const bool is_conv = boost::is_convertible< typename detail::segment_iterator::iterator_type < OtherGeometry >::type, typename detail::segment_iterator::iterator_type::type >::value; BOOST_MPL_ASSERT_MSG((is_conv), NOT_CONVERTIBLE, (segment_iterator)); } inline segment_iterator& operator++() // prefix { base::operator++(); return *this; } inline segment_iterator& operator--() // prefix { base::operator--(); return *this; } inline segment_iterator operator++(int) // postfix { segment_iterator copy(*this); base::operator++(); return copy; } inline segment_iterator operator--(int) // postfix { segment_iterator copy(*this); base::operator--(); return copy; } }; // MK:: need to add doc here template inline segment_iterator segments_begin(Geometry const& geometry) { return dispatch::segments_begin::apply(geometry); } // MK:: need to add doc here template inline segment_iterator segments_end(Geometry const& geometry) { return dispatch::segments_end::apply(geometry); } }} // namespace boost::geometry #endif // BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP