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_CORE_INTERIOR_RINGS_HPP
15 #define BOOST_GEOMETRY_CORE_INTERIOR_RINGS_HPP
16 
17 #include <cstddef>
18 
19 #include <boost/mpl/assert.hpp>
20 #include <boost/range/value_type.hpp>
21 #include <boost/type_traits/remove_const.hpp>
22 
23 #include <boost/geometry/core/tag.hpp>
24 #include <boost/geometry/core/tags.hpp>
25 #include <boost/geometry/core/interior_type.hpp>
26 
27 namespace boost { namespace geometry
28 {
29 
30 namespace traits
31 {
32 
33 
34 /*!
35     \brief Traits class defining access to interior_rings of a polygon
36     \details defines access (const and non const) to interior ring
37     \ingroup traits
38     \par Geometries:
39         - polygon
40     \par Specializations should provide:
41         - static inline INTERIOR& get(POLY&)
42         - static inline const INTERIOR& get(POLY const&)
43     \tparam Geometry geometry
44 */
45 template <typename Geometry>
46 struct interior_rings
47 {
48     BOOST_MPL_ASSERT_MSG
49         (
50             false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
51             , (types<Geometry>)
52         );
53 };
54 
55 
56 } // namespace traits
57 
58 
59 
60 
61 #ifndef DOXYGEN_NO_DISPATCH
62 namespace core_dispatch
63 {
64 
65 template
66 <
67     typename GeometryTag,
68     typename Geometry
69 >
70 struct interior_rings {};
71 
72 
73 template <typename Polygon>
74 struct interior_rings<polygon_tag, Polygon>
75 {
76     static inline
77     typename geometry::interior_return_type<Polygon>::type
applyboost::geometry::core_dispatch::interior_rings78                 apply(Polygon& polygon)
79     {
80         return traits::interior_rings
81             <
82                 typename boost::remove_const<Polygon>::type
83             >::get(polygon);
84     }
85 };
86 
87 
88 template <typename MultiPolygon>
89 struct interior_type<multi_polygon_tag, MultiPolygon>
90 {
91     typedef typename core_dispatch::interior_type
92         <
93             polygon_tag,
94             typename boost::range_value<MultiPolygon>::type
95         >::type type;
96 };
97 
98 
99 } // namespace core_dispatch
100 #endif
101 
102 
103 
104 /*!
105 \brief Function to get the interior rings of a polygon (non const version)
106 \ingroup interior_rings
107 \note OGC compliance: instead of InteriorRingN
108 \tparam Polygon polygon type
109 \param polygon the polygon to get the interior rings from
110 \return the interior rings (possibly a reference)
111 */
112 
113 template <typename Polygon>
interior_rings(Polygon & polygon)114 inline typename interior_return_type<Polygon>::type interior_rings(Polygon& polygon)
115 {
116     return core_dispatch::interior_rings
117         <
118             typename tag<Polygon>::type,
119             Polygon
120         >::apply(polygon);
121 }
122 
123 
124 /*!
125 \brief Function to get the interior rings of a polygon (const version)
126 \ingroup interior_rings
127 \note OGC compliance: instead of InteriorRingN
128 \tparam Polygon polygon type
129 \param polygon the polygon to get the interior rings from
130 \return the interior rings (possibly a const reference)
131 
132 \qbk{distinguish,const version}
133 */
134 template <typename Polygon>
interior_rings(Polygon const & polygon)135 inline typename interior_return_type<Polygon const>::type interior_rings(
136             Polygon const& polygon)
137 {
138     return core_dispatch::interior_rings
139         <
140             typename tag<Polygon>::type,
141             Polygon const
142         >::apply(polygon);
143 }
144 
145 
146 
147 }} // namespace boost::geometry
148 
149 
150 #endif // BOOST_GEOMETRY_CORE_INTERIOR_RINGS_HPP
151