]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/include/boost/geometry/algorithms/detail/recalculate.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / algorithms / detail / recalculate.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2013 Barend Gehrels, Amsterdam, the Netherlands.
4// Copyright (c) 2013 Bruno Lalande, Paris, France.
5// Copyright (c) 2013 Mateusz Loskot, London, UK.
6// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
7
8// Use, modification and distribution is subject to the Boost Software License,
9// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10// http://www.boost.org/LICENSE_1_0.txt)
11
12#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RECALCULATE_HPP
13#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RECALCULATE_HPP
14
15
16#include <cstddef>
17
18#include <boost/concept/requires.hpp>
19#include <boost/concept_check.hpp>
20#include <boost/mpl/assert.hpp>
21#include <boost/mpl/if.hpp>
22#include <boost/numeric/conversion/bounds.hpp>
23#include <boost/numeric/conversion/cast.hpp>
24#include <boost/range/begin.hpp>
25#include <boost/range/end.hpp>
26#include <boost/range/iterator.hpp>
27#include <boost/range/size.hpp>
28
29#include <boost/geometry/arithmetic/arithmetic.hpp>
30#include <boost/geometry/algorithms/append.hpp>
31#include <boost/geometry/algorithms/clear.hpp>
32#include <boost/geometry/core/access.hpp>
33#include <boost/geometry/core/interior_rings.hpp>
34#include <boost/geometry/core/exterior_ring.hpp>
35#include <boost/geometry/core/tags.hpp>
36
37#include <boost/geometry/geometries/concepts/check.hpp>
38
39
40namespace boost { namespace geometry
41{
42
43#ifndef DOXYGEN_NO_DETAIL
44namespace detail { namespace recalculate
45{
46
47template <std::size_t Dimension>
48struct recalculate_point
49{
50 template <typename Point1, typename Point2, typename Strategy>
51 static inline void apply(Point1& point1, Point2 const& point2, Strategy const& strategy)
52 {
53 std::size_t const dim = Dimension - 1;
54 geometry::set<dim>(point1, strategy.template apply<dim>(geometry::get<dim>(point2)));
55 recalculate_point<dim>::apply(point1, point2, strategy);
56 }
57};
58
59template <>
60struct recalculate_point<0>
61{
62 template <typename Point1, typename Point2, typename Strategy>
63 static inline void apply(Point1&, Point2 const&, Strategy const&)
64 {
65 }
66};
67
68
69template <std::size_t Dimension>
70struct recalculate_indexed
71{
72 template <typename Geometry1, typename Geometry2, typename Strategy>
73 static inline void apply(Geometry1& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
74 {
75 // Do it for both indices in one dimension
76 static std::size_t const dim = Dimension - 1;
77 geometry::set<0, dim>(geometry1, strategy.template apply<dim>(geometry::get<0, dim>(geometry2)));
78 geometry::set<1, dim>(geometry1, strategy.template apply<dim>(geometry::get<1, dim>(geometry2)));
79 recalculate_indexed<dim>::apply(geometry1, geometry2, strategy);
80 }
81};
82
83template <>
84struct recalculate_indexed<0>
85{
86
87 template <typename Geometry1, typename Geometry2, typename Strategy>
88 static inline void apply(Geometry1& , Geometry2 const& , Strategy const& )
89 {
90 }
91};
92
93struct range_to_range
94{
95 template
96 <
97 typename Range1,
98 typename Range2,
99 typename Strategy
100 >
101 static inline void apply(Range1& destination, Range2 const& source,
102 Strategy const& strategy)
103 {
104 typedef typename geometry::point_type<Range2>::type point_type;
105 typedef recalculate_point<geometry::dimension<point_type>::value> per_point;
106 geometry::clear(destination);
107
108 for (typename boost::range_iterator<Range2 const>::type it
109 = boost::begin(source);
110 it != boost::end(source);
111 ++it)
112 {
113 point_type p;
114 per_point::apply(p, *it, strategy);
115 geometry::append(destination, p);
116 }
117 }
118};
119
120struct polygon_to_polygon
121{
122private:
123 template
124 <
125 typename IteratorIn,
126 typename IteratorOut,
127 typename Strategy
128 >
129 static inline void iterate(IteratorIn begin, IteratorIn end,
130 IteratorOut it_out,
131 Strategy const& strategy)
132 {
133 for (IteratorIn it_in = begin; it_in != end; ++it_in, ++it_out)
134 {
135 range_to_range::apply(*it_out, *it_in, strategy);
136 }
137 }
138
139 template
140 <
141 typename InteriorRingsOut,
142 typename InteriorRingsIn,
143 typename Strategy
144 >
145 static inline void apply_interior_rings(
146 InteriorRingsOut& interior_rings_out,
147 InteriorRingsIn const& interior_rings_in,
148 Strategy const& strategy)
149 {
150 traits::resize<InteriorRingsOut>::apply(interior_rings_out,
151 boost::size(interior_rings_in));
152
153 iterate(
154 boost::begin(interior_rings_in), boost::end(interior_rings_in),
155 boost::begin(interior_rings_out),
156 strategy);
157 }
158
159public:
160 template
161 <
162 typename Polygon1,
163 typename Polygon2,
164 typename Strategy
165 >
166 static inline void apply(Polygon1& destination, Polygon2 const& source,
167 Strategy const& strategy)
168 {
169 range_to_range::apply(geometry::exterior_ring(destination),
170 geometry::exterior_ring(source), strategy);
171
172 apply_interior_rings(geometry::interior_rings(destination),
173 geometry::interior_rings(source), strategy);
174 }
175};
176
177}} // namespace detail::recalculate
178#endif // DOXYGEN_NO_DETAIL
179
180#ifndef DOXYGEN_NO_DISPATCH
181namespace dispatch
182{
183
184template
185<
186 typename Geometry1,
187 typename Geometry2,
188 typename Tag1 = typename geometry::tag<Geometry1>::type,
189 typename Tag2 = typename geometry::tag<Geometry2>::type
190>
191struct recalculate : not_implemented<Tag1, Tag2>
192{};
193
194template <typename Point1, typename Point2>
195struct recalculate<Point1, Point2, point_tag, point_tag>
196 : detail::recalculate::recalculate_point<geometry::dimension<Point1>::value>
197{};
198
199template <typename Box1, typename Box2>
200struct recalculate<Box1, Box2, box_tag, box_tag>
201 : detail::recalculate::recalculate_indexed<geometry::dimension<Box1>::value>
202{};
203
204template <typename Segment1, typename Segment2>
205struct recalculate<Segment1, Segment2, segment_tag, segment_tag>
206 : detail::recalculate::recalculate_indexed<geometry::dimension<Segment1>::value>
207{};
208
209template <typename Polygon1, typename Polygon2>
210struct recalculate<Polygon1, Polygon2, polygon_tag, polygon_tag>
211 : detail::recalculate::polygon_to_polygon
212{};
213
214} // namespace dispatch
215#endif // DOXYGEN_NO_DISPATCH
216
217
218
219template <typename Geometry1, typename Geometry2, typename Strategy>
220inline void recalculate(Geometry1& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
221{
222 concepts::check<Geometry1>();
223 concepts::check<Geometry2 const>();
224
225 // static assert dimensions (/types) are the same
226
227 dispatch::recalculate<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
228}
229
230
231}} // namespace boost::geometry
232
233
234#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RECALCULATE_HPP