// 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_POINT_ITERATOR_HPP #define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP #include #include #include #include #include #include #include #include #include namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { // specializations for points_begin template struct points_begin { static inline typename detail::point_iterator::iterator_type < Linestring >::type apply(Linestring& linestring) { return boost::begin(linestring); } }; template struct points_begin { static inline typename detail::point_iterator::iterator_type::type apply(Ring& ring) { return boost::begin(ring); } }; template struct points_begin { typedef typename detail::point_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 (boost::begin(geometry::exterior_ring(polygon)), boost::end(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 points_begin { static inline typename detail::point_iterator::iterator_type < MultiPoint >::type apply(MultiPoint& multipoint) { return boost::begin(multipoint); } }; template struct points_begin { typedef typename detail::point_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 points_begin { typedef typename detail::point_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 points_end template struct points_end { static inline typename detail::point_iterator::iterator_type < Linestring >::type apply(Linestring& linestring) { return boost::end(linestring); } }; template struct points_end { static inline typename detail::point_iterator::iterator_type::type apply(Ring& ring) { return boost::end(ring); } }; template struct points_end { typedef typename detail::point_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 (boost::end(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 points_end { static inline typename detail::point_iterator::iterator_type < MultiPoint >::type apply(MultiPoint& multipoint) { return boost::end(multipoint); } }; template struct points_end { typedef typename detail::point_iterator::iterator_type < MultiLinestring >::type return_type; static inline return_type apply(MultiLinestring& multilinestring) { return return_type(boost::end(multilinestring)); } }; template struct points_end { typedef typename detail::point_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 point_iterator : public detail::point_iterator::iterator_type::type { private: typedef typename detail::point_iterator::iterator_type::type base; inline base* base_ptr() { return this; } inline base const* base_ptr() const { return this; } template friend class point_iterator; template friend inline point_iterator points_begin(G&); template friend inline point_iterator points_end(G&); inline point_iterator(base const& base_it) : base(base_it) {} public: inline point_iterator() {} template inline point_iterator(point_iterator const& other) : base(*other.base_ptr()) { static const bool is_conv = boost::is_convertible< typename detail::point_iterator::iterator_type < OtherGeometry >::type, typename detail::point_iterator::iterator_type < Geometry >::type >::value; BOOST_MPL_ASSERT_MSG((is_conv), NOT_CONVERTIBLE, (point_iterator)); } }; // MK:: need to add doc here template inline point_iterator points_begin(Geometry& geometry) { return dispatch::points_begin::apply(geometry); } // MK:: need to add doc here template inline point_iterator points_end(Geometry& geometry) { return dispatch::points_end::apply(geometry); } }} // namespace boost::geometry #endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP