]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/reverse.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / reverse.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 // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
7
8 // This file was modified by Oracle on 2020.
9 // Modifications copyright (c) 2020 Oracle and/or its affiliates.
10 // Contributed and/or modified by Adam Wulkiewicz, 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 #ifndef BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
20 #define BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
21
22 #include <algorithm>
23
24 #include <boost/range/begin.hpp>
25 #include <boost/range/end.hpp>
26
27 #include <boost/variant/apply_visitor.hpp>
28 #include <boost/variant/static_visitor.hpp>
29 #include <boost/variant/variant_fwd.hpp>
30
31 #include <boost/geometry/algorithms/detail/interior_iterator.hpp>
32 #include <boost/geometry/algorithms/detail/multi_modify.hpp>
33 #include <boost/geometry/core/interior_rings.hpp>
34 #include <boost/geometry/core/tags.hpp>
35 #include <boost/geometry/geometries/concepts/check.hpp>
36
37
38 namespace boost { namespace geometry
39 {
40
41
42 #ifndef DOXYGEN_NO_DETAIL
43 namespace detail { namespace reverse
44 {
45
46
47 struct range_reverse
48 {
49 template <typename Range>
50 static inline void apply(Range& range)
51 {
52 std::reverse(boost::begin(range), boost::end(range));
53 }
54 };
55
56
57 struct polygon_reverse: private range_reverse
58 {
59 template <typename Polygon>
60 static inline void apply(Polygon& polygon)
61 {
62 range_reverse::apply(exterior_ring(polygon));
63
64 typename interior_return_type<Polygon>::type
65 rings = interior_rings(polygon);
66
67 for (typename detail::interior_iterator<Polygon>::type
68 it = boost::begin(rings); it != boost::end(rings); ++it)
69 {
70 range_reverse::apply(*it);
71 }
72 }
73 };
74
75
76 }} // namespace detail::reverse
77 #endif // DOXYGEN_NO_DETAIL
78
79
80 #ifndef DOXYGEN_NO_DISPATCH
81 namespace dispatch
82 {
83
84
85 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
86 struct reverse
87 {
88 static inline void apply(Geometry&)
89 {}
90 };
91
92
93 template <typename Ring>
94 struct reverse<Ring, ring_tag>
95 : detail::reverse::range_reverse
96 {};
97
98
99 template <typename LineString>
100 struct reverse<LineString, linestring_tag>
101 : detail::reverse::range_reverse
102 {};
103
104
105 template <typename Polygon>
106 struct reverse<Polygon, polygon_tag>
107 : detail::reverse::polygon_reverse
108 {};
109
110
111 template <typename Geometry>
112 struct reverse<Geometry, multi_linestring_tag>
113 : detail::multi_modify
114 <
115 Geometry,
116 detail::reverse::range_reverse
117 >
118 {};
119
120
121 template <typename Geometry>
122 struct reverse<Geometry, multi_polygon_tag>
123 : detail::multi_modify
124 <
125 Geometry,
126 detail::reverse::polygon_reverse
127 >
128 {};
129
130
131
132 } // namespace dispatch
133 #endif
134
135
136 namespace resolve_variant
137 {
138
139 template <typename Geometry>
140 struct reverse
141 {
142 static void apply(Geometry& geometry)
143 {
144 concepts::check<Geometry>();
145 dispatch::reverse<Geometry>::apply(geometry);
146 }
147 };
148
149 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
150 struct reverse<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
151 {
152 struct visitor: boost::static_visitor<void>
153 {
154 template <typename Geometry>
155 void operator()(Geometry& geometry) const
156 {
157 reverse<Geometry>::apply(geometry);
158 }
159 };
160
161 static inline void apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry)
162 {
163 boost::apply_visitor(visitor(), geometry);
164 }
165 };
166
167 } // namespace resolve_variant
168
169
170 /*!
171 \brief Reverses the points within a geometry
172 \details Generic function to reverse a geometry. It resembles the std::reverse
173 functionality, but it takes the geometry type into account. Only for a ring
174 or for a linestring it is the same as the std::reverse.
175 \ingroup reverse
176 \tparam Geometry \tparam_geometry
177 \param geometry \param_geometry which will be reversed
178
179 \qbk{[include reference/algorithms/reverse.qbk]}
180 */
181 template <typename Geometry>
182 inline void reverse(Geometry& geometry)
183 {
184 resolve_variant::reverse<Geometry>::apply(geometry);
185 }
186
187 }} // namespace boost::geometry
188
189
190 #endif // BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP