change support python version
[platform/upstream/boost.git] / boost / geometry / algorithms / detail / sections / range_by_section.hpp
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 // This file was modified by Oracle on 2013, 2014.
11 // Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates.
12
13 // Use, modification and distribution is subject to the Boost Software License,
14 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
16
17 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
18
19 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
20 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
21
22 #include <boost/mpl/assert.hpp>
23 #include <boost/range.hpp>
24
25 #include <boost/geometry/core/access.hpp>
26 #include <boost/geometry/core/assert.hpp>
27 #include <boost/geometry/core/closure.hpp>
28 #include <boost/geometry/core/exterior_ring.hpp>
29 #include <boost/geometry/core/interior_rings.hpp>
30 #include <boost/geometry/core/ring_type.hpp>
31 #include <boost/geometry/core/tags.hpp>
32 #include <boost/geometry/geometries/concepts/check.hpp>
33 #include <boost/geometry/util/range.hpp>
34
35
36 namespace boost { namespace geometry
37 {
38
39 #ifndef DOXYGEN_NO_DETAIL
40 namespace detail { namespace section
41 {
42
43
44 template <typename Range, typename Section>
45 struct full_section_range
46 {
47     static inline Range const& apply(Range const& range, Section const& )
48     {
49         return range;
50     }
51 };
52
53
54 template <typename Polygon, typename Section>
55 struct full_section_polygon
56 {
57     static inline typename ring_return_type<Polygon const>::type apply(Polygon const& polygon, Section const& section)
58     {
59         return section.ring_id.ring_index < 0
60             ? geometry::exterior_ring(polygon)
61             : range::at(geometry::interior_rings(polygon),
62                         static_cast<std::size_t>(section.ring_id.ring_index));
63     }
64 };
65
66
67 template
68 <
69     typename MultiGeometry,
70     typename Section,
71     typename Policy
72 >
73 struct full_section_multi
74 {
75     static inline typename ring_return_type<MultiGeometry const>::type apply(
76                 MultiGeometry const& multi, Section const& section)
77     {
78         typedef typename boost::range_size<MultiGeometry>::type size_type;
79
80         BOOST_GEOMETRY_ASSERT
81             (
82                 section.ring_id.multi_index >= 0
83                 && size_type(section.ring_id.multi_index) < boost::size(multi)
84             );
85
86         return Policy::apply(range::at(multi, size_type(section.ring_id.multi_index)), section);
87     }
88 };
89
90
91 }} // namespace detail::section
92 #endif
93
94
95 #ifndef DOXYGEN_NO_DISPATCH
96 namespace dispatch
97 {
98
99
100 template
101 <
102     typename Tag,
103     typename Geometry,
104     typename Section
105 >
106 struct range_by_section
107 {
108     BOOST_MPL_ASSERT_MSG
109         (
110             false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
111             , (types<Geometry>)
112         );
113 };
114
115
116 template <typename LineString, typename Section>
117 struct range_by_section<linestring_tag, LineString, Section>
118     : detail::section::full_section_range<LineString, Section>
119 {};
120
121
122 template <typename Ring, typename Section>
123 struct range_by_section<ring_tag, Ring, Section>
124     : detail::section::full_section_range<Ring, Section>
125 {};
126
127
128 template <typename Polygon, typename Section>
129 struct range_by_section<polygon_tag, Polygon, Section>
130     : detail::section::full_section_polygon<Polygon, Section>
131 {};
132
133
134 template <typename MultiPolygon, typename Section>
135 struct range_by_section<multi_polygon_tag, MultiPolygon, Section>
136     : detail::section::full_section_multi
137         <
138             MultiPolygon,
139             Section,
140             detail::section::full_section_polygon
141                 <
142                     typename boost::range_value<MultiPolygon>::type,
143                     Section
144                 >
145        >
146 {};
147
148 template <typename MultiLinestring, typename Section>
149 struct range_by_section<multi_linestring_tag, MultiLinestring, Section>
150     : detail::section::full_section_multi
151         <
152             MultiLinestring,
153             Section,
154             detail::section::full_section_range
155                 <
156                     typename boost::range_value<MultiLinestring>::type,
157                     Section
158                 >
159        >
160 {};
161
162
163 } // namespace dispatch
164 #endif
165
166
167 /*!
168     \brief Get full ring (exterior, one of interiors, one from multi)
169         indicated by the specified section
170     \ingroup sectionalize
171     \tparam Geometry type
172     \tparam Section type of section to get from
173     \param geometry geometry to take section of
174     \param section structure with section
175  */
176 template <typename Geometry, typename Section>
177 inline typename ring_return_type<Geometry const>::type
178             range_by_section(Geometry const& geometry, Section const& section)
179 {
180     concepts::check<Geometry const>();
181
182     return dispatch::range_by_section
183         <
184             typename tag<Geometry>::type,
185             Geometry,
186             Section
187         >::apply(geometry, section);
188 }
189
190
191 }} // namespace boost::geometry
192
193 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP