1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. 6 7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 9 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) 13 14 #ifndef BOOST_GEOMETRY_VIEWS_BOX_VIEW_HPP 15 #define BOOST_GEOMETRY_VIEWS_BOX_VIEW_HPP 16 17 18 #include <boost/range.hpp> 19 20 #include <boost/geometry/core/point_type.hpp> 21 #include <boost/geometry/views/detail/points_view.hpp> 22 #include <boost/geometry/algorithms/assign.hpp> 23 24 25 namespace boost { namespace geometry 26 { 27 28 29 /*! 30 \brief Makes a box behave like a ring or a range 31 \details Adapts a box to the Boost.Range concept, enabling the user to iterating 32 box corners. The box_view is registered as a Ring Concept 33 \tparam Box \tparam_geometry{Box} 34 \tparam Clockwise If true, walks in clockwise direction, otherwise 35 it walks in counterclockwise direction 36 \ingroup views 37 38 \qbk{before.synopsis, 39 [heading Model of] 40 [link geometry.reference.concepts.concept_ring Ring Concept] 41 } 42 43 \qbk{[include reference/views/box_view.qbk]} 44 */ 45 template <typename Box, bool Clockwise = true> 46 struct box_view 47 : public detail::points_view 48 < 49 typename geometry::point_type<Box>::type, 50 5 51 > 52 { 53 typedef typename geometry::point_type<Box>::type point_type; 54 55 /// Constructor accepting the box to adapt box_viewboost::geometry::box_view56 explicit box_view(Box const& box) 57 : detail::points_view<point_type, 5>(copy_policy(box)) 58 {} 59 60 private : 61 62 class copy_policy 63 { 64 public : copy_policy(Box const & box)65 inline copy_policy(Box const& box) 66 : m_box(box) 67 {} 68 apply(point_type * points) const69 inline void apply(point_type* points) const 70 { 71 // assign_box_corners_oriented requires a range 72 // an alternative for this workaround would be to pass a range here, 73 // e.g. use boost::array in points_view instead of c-array 74 std::pair<point_type*, point_type*> rng = std::make_pair(points, points + 5); 75 detail::assign_box_corners_oriented<!Clockwise>(m_box, rng); 76 points[4] = points[0]; 77 } 78 private : 79 Box const& m_box; 80 }; 81 82 }; 83 84 85 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS 86 87 // All views on boxes are handled as rings 88 namespace traits 89 { 90 91 template<typename Box, bool Clockwise> 92 struct tag<box_view<Box, Clockwise> > 93 { 94 typedef ring_tag type; 95 }; 96 97 template<typename Box> 98 struct point_order<box_view<Box, false> > 99 { 100 static order_selector const value = counterclockwise; 101 }; 102 103 104 template<typename Box> 105 struct point_order<box_view<Box, true> > 106 { 107 static order_selector const value = clockwise; 108 }; 109 110 } 111 112 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS 113 114 115 }} // namespace boost::geometry 116 117 118 #endif // BOOST_GEOMETRY_VIEWS_BOX_VIEW_HPP 119