1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. 6 7 // This file was modified by Oracle on 2015. 8 // Modifications copyright (c) 2015, Oracle and/or its affiliates. 9 10 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 11 12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 14 15 // Use, modification and distribution is subject to the Boost Software License, 16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 17 // http://www.boost.org/LICENSE_1_0.txt) 18 19 20 #ifndef BOOST_GEOMETRY_CORE_RING_TYPE_HPP 21 #define BOOST_GEOMETRY_CORE_RING_TYPE_HPP 22 23 24 #include <boost/mpl/assert.hpp> 25 #include <boost/mpl/if.hpp> 26 #include <boost/range/value_type.hpp> 27 #include <boost/type_traits/is_const.hpp> 28 #include <boost/type_traits/remove_const.hpp> 29 #include <boost/type_traits/remove_reference.hpp> 30 31 #include <boost/geometry/core/tag.hpp> 32 #include <boost/geometry/core/tags.hpp> 33 34 35 namespace boost { namespace geometry 36 { 37 38 namespace traits 39 { 40 41 42 /*! 43 \brief Traits class to indicate ring-type of a polygon's exterior ring/interior rings 44 \ingroup traits 45 \par Geometries: 46 - polygon 47 \par Specializations should provide: 48 - typedef XXX type ( e.g. ring<P> ) 49 \tparam Geometry geometry 50 */ 51 template <typename Geometry> 52 struct ring_const_type 53 { 54 BOOST_MPL_ASSERT_MSG 55 ( 56 false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE 57 , (types<Geometry>) 58 ); 59 }; 60 61 template <typename Geometry> 62 struct ring_mutable_type 63 { 64 BOOST_MPL_ASSERT_MSG 65 ( 66 false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE 67 , (types<Geometry>) 68 ); 69 }; 70 71 72 } // namespace traits 73 74 75 #ifndef DOXYGEN_NO_DISPATCH 76 namespace core_dispatch 77 { 78 79 template <typename GeometryTag, typename Geometry> 80 struct ring_return_type 81 {}; 82 83 84 template <typename LineString> 85 struct ring_return_type<linestring_tag, LineString> 86 { 87 typedef LineString& type; 88 }; 89 90 91 template <typename Ring> 92 struct ring_return_type<ring_tag, Ring> 93 { 94 typedef Ring& type; 95 }; 96 97 98 template <typename Polygon> 99 struct ring_return_type<polygon_tag, Polygon> 100 { 101 typedef typename boost::remove_const<Polygon>::type nc_polygon_type; 102 103 typedef typename boost::mpl::if_ 104 < 105 boost::is_const<Polygon>, 106 typename traits::ring_const_type<nc_polygon_type>::type, 107 typename traits::ring_mutable_type<nc_polygon_type>::type 108 >::type type; 109 }; 110 111 112 template <typename MultiLinestring> 113 struct ring_return_type<multi_linestring_tag, MultiLinestring> 114 { 115 typedef typename ring_return_type 116 < 117 linestring_tag, 118 typename boost::mpl::if_ 119 < 120 boost::is_const<MultiLinestring>, 121 typename boost::range_value<MultiLinestring>::type const, 122 typename boost::range_value<MultiLinestring>::type 123 >::type 124 >::type type; 125 }; 126 127 128 template <typename MultiPolygon> 129 struct ring_return_type<multi_polygon_tag, MultiPolygon> 130 { 131 typedef typename ring_return_type 132 < 133 polygon_tag, 134 typename boost::mpl::if_ 135 < 136 boost::is_const<MultiPolygon>, 137 typename boost::range_value<MultiPolygon>::type const, 138 typename boost::range_value<MultiPolygon>::type 139 >::type 140 >::type type; 141 }; 142 143 144 template <typename GeometryTag, typename Geometry> 145 struct ring_type 146 {}; 147 148 149 template <typename Ring> 150 struct ring_type<ring_tag, Ring> 151 { 152 typedef Ring type; 153 }; 154 155 156 template <typename Polygon> 157 struct ring_type<polygon_tag, Polygon> 158 { 159 typedef typename boost::remove_reference 160 < 161 typename ring_return_type<polygon_tag, Polygon>::type 162 >::type type; 163 }; 164 165 166 template <typename MultiLinestring> 167 struct ring_type<multi_linestring_tag, MultiLinestring> 168 { 169 typedef typename boost::remove_reference 170 < 171 typename ring_return_type<multi_linestring_tag, MultiLinestring>::type 172 >::type type; 173 }; 174 175 176 template <typename MultiPolygon> 177 struct ring_type<multi_polygon_tag, MultiPolygon> 178 { 179 typedef typename boost::remove_reference 180 < 181 typename ring_return_type<multi_polygon_tag, MultiPolygon>::type 182 >::type type; 183 }; 184 185 186 } // namespace core_dispatch 187 #endif 188 189 190 /*! 191 \brief \brief_meta{type, ring_type, \meta_geometry_type} 192 \details A polygon contains one exterior ring 193 and zero or more interior rings (holes). 194 This metafunction retrieves the type of the rings. 195 Exterior ring and each of the interior rings all have the same ring_type. 196 \tparam Geometry A type fullfilling the Ring, Polygon or MultiPolygon concept. 197 \ingroup core 198 199 \qbk{[include reference/core/ring_type.qbk]} 200 */ 201 template <typename Geometry> 202 struct ring_type 203 { 204 typedef typename core_dispatch::ring_type 205 < 206 typename tag<Geometry>::type, 207 Geometry 208 >::type type; 209 }; 210 211 212 template <typename Geometry> 213 struct ring_return_type 214 { 215 typedef typename core_dispatch::ring_return_type 216 < 217 typename tag<Geometry>::type, 218 Geometry 219 >::type type; 220 }; 221 222 223 }} // namespace boost::geometry 224 225 226 #endif // BOOST_GEOMETRY_CORE_RING_TYPE_HPP 227