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 // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. 7 8 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 9 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 10 11 // Use, modification and distribution is subject to the Boost Software License, 12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 13 // http://www.boost.org/LICENSE_1_0.txt) 14 15 #ifndef BOOST_GEOMETRY_GEOMETRIES_RING_HPP 16 #define BOOST_GEOMETRY_GEOMETRIES_RING_HPP 17 18 #include <memory> 19 #include <vector> 20 21 #include <boost/concept/assert.hpp> 22 23 #include <boost/geometry/core/closure.hpp> 24 #include <boost/geometry/core/point_order.hpp> 25 #include <boost/geometry/core/tag.hpp> 26 #include <boost/geometry/core/tags.hpp> 27 28 #include <boost/geometry/geometries/concepts/point_concept.hpp> 29 30 #include <boost/config.hpp> 31 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST 32 #include <initializer_list> 33 #endif 34 35 namespace boost { namespace geometry 36 { 37 38 namespace model 39 { 40 /*! 41 \brief A ring (aka linear ring) is a closed line which should not be selfintersecting 42 \ingroup geometries 43 \tparam Point point type 44 \tparam ClockWise true for clockwise direction, 45 false for CounterClockWise direction 46 \tparam Closed true for closed polygons (last point == first point), 47 false open points 48 \tparam Container container type, for example std::vector, std::deque 49 \tparam Allocator container-allocator-type 50 51 \qbk{[include reference/geometries/ring.qbk]} 52 \qbk{before.synopsis, 53 [heading Model of] 54 [link geometry.reference.concepts.concept_ring Ring Concept] 55 } 56 */ 57 template 58 < 59 typename Point, 60 bool ClockWise = true, bool Closed = true, 61 template<typename, typename> class Container = std::vector, 62 template<typename> class Allocator = std::allocator 63 > 64 class ring : public Container<Point, Allocator<Point> > 65 { 66 BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) ); 67 68 typedef Container<Point, Allocator<Point> > base_type; 69 70 public : 71 /// \constructor_default{ring} ring()72 inline ring() 73 : base_type() 74 {} 75 76 /// \constructor_begin_end{ring} 77 template <typename Iterator> ring(Iterator begin,Iterator end)78 inline ring(Iterator begin, Iterator end) 79 : base_type(begin, end) 80 {} 81 82 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST 83 84 /// \constructor_initializer_list{ring} ring(std::initializer_list<Point> l)85 inline ring(std::initializer_list<Point> l) 86 : base_type(l.begin(), l.end()) 87 {} 88 89 // Commented out for now in order to support Boost.Assign 90 // Without this assignment operator first the object should be created 91 // from initializer list, then it shoudl be moved. 92 //// Without this workaround in MSVC the assignment operator is ambiguous 93 //#ifndef BOOST_MSVC 94 // /// \assignment_initializer_list{ring} 95 // inline ring & operator=(std::initializer_list<Point> l) 96 // { 97 // base_type::assign(l.begin(), l.end()); 98 // return *this; 99 // } 100 //#endif 101 102 #endif 103 }; 104 105 } // namespace model 106 107 108 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS 109 namespace traits 110 { 111 112 template 113 < 114 typename Point, 115 bool ClockWise, bool Closed, 116 template<typename, typename> class Container, 117 template<typename> class Allocator 118 > 119 struct tag<model::ring<Point, ClockWise, Closed, Container, Allocator> > 120 { 121 typedef ring_tag type; 122 }; 123 124 125 template 126 < 127 typename Point, 128 bool Closed, 129 template<typename, typename> class Container, 130 template<typename> class Allocator 131 > 132 struct point_order<model::ring<Point, false, Closed, Container, Allocator> > 133 { 134 static const order_selector value = counterclockwise; 135 }; 136 137 138 template 139 < 140 typename Point, 141 bool Closed, 142 template<typename, typename> class Container, 143 template<typename> class Allocator 144 > 145 struct point_order<model::ring<Point, true, Closed, Container, Allocator> > 146 { 147 static const order_selector value = clockwise; 148 }; 149 150 template 151 < 152 typename Point, 153 bool PointOrder, 154 template<typename, typename> class Container, 155 template<typename> class Allocator 156 > 157 struct closure<model::ring<Point, PointOrder, true, Container, Allocator> > 158 { 159 static const closure_selector value = closed; 160 }; 161 162 template 163 < 164 typename Point, 165 bool PointOrder, 166 template<typename, typename> class Container, 167 template<typename> class Allocator 168 > 169 struct closure<model::ring<Point, PointOrder, false, Container, Allocator> > 170 { 171 static const closure_selector value = open; 172 }; 173 174 175 } // namespace traits 176 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS 177 178 179 }} // namespace boost::geometry 180 181 #endif // BOOST_GEOMETRY_GEOMETRIES_RING_HPP 182