1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2018.
6 // Modifications copyright (c) 2018, Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
14 #ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP
15 #define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP
17 // Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
18 // boost::polygon::polygon_with_holes_data -> boost::geometry::polygon
19 // pair{begin_points, end_points} -> ring_proxy
21 #include <boost/polygon/polygon.hpp>
22 #include <boost/range/const_iterator.hpp>
23 #include <boost/range/mutable_iterator.hpp>
25 #include <boost/geometry/core/mutable_range.hpp>
26 #include <boost/geometry/core/tag.hpp>
28 namespace boost { namespace geometry
31 namespace adapt { namespace bp
37 template <bool Mutable>
44 template <typename Ring, typename Point>
45 static inline void push_back(Ring& ring, Point const& point)
47 // Boost.Polygon's polygons are not appendable. So create a temporary vector,
48 // add a record and set it to the original. Of course: this is not efficient.
49 // But there seems no other way (without using a wrapper)
50 std::vector<Point> temporary_vector
52 boost::polygon::begin_points(ring),
53 boost::polygon::end_points(ring)
55 temporary_vector.push_back(point);
56 boost::polygon::set_points(ring, temporary_vector.begin(), temporary_vector.end());
64 template <typename Ring, typename Point>
65 static inline void push_back(Ring& /*ring*/, Point const& /*point*/)
75 // Polygon should implement the boost::polygon::polygon_with_holes_concept
76 // Specify constness in the template parameter if necessary
77 template<typename Polygon>
81 typedef typename boost::polygon::polygon_traits
83 typename boost::remove_const<Polygon>::type
84 >::iterator_type iterator_type;
86 typedef typename boost::polygon::polygon_with_holes_traits
88 typename boost::remove_const<Polygon>::type
89 >::iterator_holes_type hole_iterator_type;
91 static const bool is_mutable = !boost::is_const<Polygon>::type::value;
93 inline ring_proxy(Polygon& p)
94 : m_polygon_pointer(&p)
98 // Constructor used from hole_iterator
99 inline ring_proxy(Polygon& p, hole_iterator_type hole_it)
100 : m_polygon_pointer(&p)
105 // Default constructor, for mutable polygons / appending (interior) rings
107 : m_polygon_pointer(&m_polygon_for_default_constructor)
112 iterator_type begin() const
115 ? boost::polygon::begin_points(*m_hole_it)
116 : boost::polygon::begin_points(*m_polygon_pointer)
120 iterator_type begin()
123 ? boost::polygon::begin_points(*m_hole_it)
124 : boost::polygon::begin_points(*m_polygon_pointer)
128 iterator_type end() const
131 ? boost::polygon::end_points(*m_hole_it)
132 : boost::polygon::end_points(*m_polygon_pointer)
139 ? boost::polygon::end_points(*m_hole_it)
140 : boost::polygon::end_points(*m_polygon_pointer)
150 // Does NOT work see comment above
154 boost::polygon::set_points(*m_polygon_pointer,
155 boost::polygon::begin_points(p),
156 boost::polygon::end_points(p));
160 void resize(std::size_t /*new_size*/)
164 // Does NOT work see comment above
168 // TODO: implement this by resizing the container
174 template <typename Point>
175 void push_back(Point const& point)
179 //detail::modify<is_mutable>::push_back(*m_hole_it, point);
180 //std::cout << "HOLE: " << typeid(*m_hole_it).name() << std::endl;
181 //std::cout << "HOLE: " << typeid(m_hole_it).name() << std::endl;
182 //std::cout << "HOLE: " << typeid(hole_iterator_type).name() << std::endl;
184 // Note, ths does NOT work because hole_iterator_type is defined
185 // as a const_iterator by Boost.Polygon
190 detail::modify<is_mutable>::push_back(*m_polygon_pointer, point);
195 Polygon* m_polygon_pointer;
197 hole_iterator_type m_hole_it;
199 Polygon m_polygon_for_default_constructor;
205 // Support geometry::adapt::bp::ring_proxy for Boost.Range ADP
206 template<typename Polygon>
207 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
208 range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy)
210 return proxy.begin();
213 template<typename Polygon>
214 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type
215 range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy)
217 return proxy.begin();
220 template<typename Polygon>
221 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
222 range_end(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy)
227 template<typename Polygon>
228 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type
229 range_end(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy)
237 }} // namespace adapt::bp
243 template <typename Polygon>
244 struct tag<adapt::bp::ring_proxy<Polygon> >
246 typedef ring_tag type;
250 template <typename Polygon>
251 struct rvalue_type<adapt::bp::ring_proxy<Polygon> >
253 typedef adapt::bp::ring_proxy<Polygon> type;
256 template <typename Polygon>
257 struct clear<adapt::bp::ring_proxy<Polygon> >
259 static inline void apply(adapt::bp::ring_proxy<Polygon> proxy)
266 template <typename Polygon>
267 struct resize<adapt::bp::ring_proxy<Polygon> >
269 static inline void apply(adapt::bp::ring_proxy<Polygon> proxy, std::size_t new_size)
271 proxy.resize(new_size);
275 template <typename Polygon>
276 struct push_back<adapt::bp::ring_proxy<Polygon> >
278 static inline void apply(adapt::bp::ring_proxy<Polygon> proxy,
279 typename boost::polygon::polygon_traits<Polygon>::point_type const& point)
281 proxy.push_back(point);
286 } // namespace traits
288 }} // namespace boost::geometry
290 // Specialize ring_proxy for Boost.Range
293 template<typename Polygon>
294 struct range_mutable_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
296 typedef typename geometry::adapt::bp::ring_proxy<Polygon>::iterator_type type;
299 template<typename Polygon>
300 struct range_const_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
302 typedef typename geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type type;
308 #endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP