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