]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/assign.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / assign.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 Samuel Debionne, Grenoble, France.
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_ASSIGN_HPP
20 #define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
21
22
23 #include <cstddef>
24
25 #include <boost/concept/requires.hpp>
26 #include <boost/concept_check.hpp>
27 #include <boost/numeric/conversion/bounds.hpp>
28 #include <boost/numeric/conversion/cast.hpp>
29
30 #include <boost/variant/apply_visitor.hpp>
31 #include <boost/variant/static_visitor.hpp>
32 #include <boost/variant/variant_fwd.hpp>
33
34 #include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
35 #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
36 #include <boost/geometry/algorithms/detail/assign_values.hpp>
37 #include <boost/geometry/algorithms/convert.hpp>
38 #include <boost/geometry/algorithms/append.hpp>
39 #include <boost/geometry/algorithms/clear.hpp>
40 #include <boost/geometry/arithmetic/arithmetic.hpp>
41 #include <boost/geometry/core/access.hpp>
42 #include <boost/geometry/core/exterior_ring.hpp>
43 #include <boost/geometry/core/static_assert.hpp>
44 #include <boost/geometry/core/tags.hpp>
45
46 #include <boost/geometry/geometries/concepts/check.hpp>
47
48 #include <boost/geometry/util/for_each_coordinate.hpp>
49
50 namespace boost { namespace geometry
51 {
52
53 /*!
54 \brief Assign a range of points to a linestring, ring or polygon
55 \note The point-type of the range might be different from the point-type of the geometry
56 \ingroup assign
57 \tparam Geometry \tparam_geometry
58 \tparam Range \tparam_range_point
59 \param geometry \param_geometry
60 \param range \param_range_point
61
62 \qbk{
63 [heading Notes]
64 [note Assign automatically clears the geometry before assigning (use append if you don't want that)]
65 [heading Example]
66 [assign_points] [assign_points_output]
67
68 [heading See also]
69 \* [link geometry.reference.algorithms.append append]
70 }
71 */
72 template <typename Geometry, typename Range>
73 inline void assign_points(Geometry& geometry, Range const& range)
74 {
75 concepts::check<Geometry>();
76
77 clear(geometry);
78 geometry::append(geometry, range, -1, 0);
79 }
80
81
82 /*!
83 \brief assign to a box inverse infinite
84 \details The assign_inverse function initialize a 2D or 3D box with large coordinates, the
85 min corner is very large, the max corner is very small. This is a convenient starting point to
86 collect the minimum bounding box of a geometry.
87 \ingroup assign
88 \tparam Geometry \tparam_geometry
89 \param geometry \param_geometry
90
91 \qbk{
92 [heading Example]
93 [assign_inverse] [assign_inverse_output]
94
95 [heading See also]
96 \* [link geometry.reference.algorithms.make.make_inverse make_inverse]
97 }
98 */
99 template <typename Geometry>
100 inline void assign_inverse(Geometry& geometry)
101 {
102 concepts::check<Geometry>();
103
104 dispatch::assign_inverse
105 <
106 typename tag<Geometry>::type,
107 Geometry
108 >::apply(geometry);
109 }
110
111 /*!
112 \brief assign zero values to a box, point
113 \ingroup assign
114 \details The assign_zero function initializes a 2D or 3D point or box with coordinates of zero
115 \tparam Geometry \tparam_geometry
116 \param geometry \param_geometry
117
118 */
119 template <typename Geometry>
120 inline void assign_zero(Geometry& geometry)
121 {
122 concepts::check<Geometry>();
123
124 dispatch::assign_zero
125 <
126 typename tag<Geometry>::type,
127 Geometry
128 >::apply(geometry);
129 }
130
131 /*!
132 \brief Assign two coordinates to a geometry (usually a 2D point)
133 \ingroup assign
134 \tparam Geometry \tparam_geometry
135 \tparam Type \tparam_numeric to specify the coordinates
136 \param geometry \param_geometry
137 \param c1 \param_x
138 \param c2 \param_y
139
140 \qbk{distinguish, 2 coordinate values}
141 \qbk{
142 [heading Example]
143 [assign_2d_point] [assign_2d_point_output]
144
145 [heading See also]
146 \* [link geometry.reference.algorithms.make.make_2_2_coordinate_values make]
147 }
148 */
149 template <typename Geometry, typename Type>
150 inline void assign_values(Geometry& geometry, Type const& c1, Type const& c2)
151 {
152 concepts::check<Geometry>();
153
154 dispatch::assign
155 <
156 typename tag<Geometry>::type,
157 Geometry,
158 geometry::dimension<Geometry>::type::value
159 >::apply(geometry, c1, c2);
160 }
161
162 /*!
163 \brief Assign three values to a geometry (usually a 3D point)
164 \ingroup assign
165 \tparam Geometry \tparam_geometry
166 \tparam Type \tparam_numeric to specify the coordinates
167 \param geometry \param_geometry
168 \param c1 \param_x
169 \param c2 \param_y
170 \param c3 \param_z
171
172 \qbk{distinguish, 3 coordinate values}
173 \qbk{
174 [heading Example]
175 [assign_3d_point] [assign_3d_point_output]
176
177 [heading See also]
178 \* [link geometry.reference.algorithms.make.make_3_3_coordinate_values make]
179 }
180 */
181 template <typename Geometry, typename Type>
182 inline void assign_values(Geometry& geometry,
183 Type const& c1, Type const& c2, Type const& c3)
184 {
185 concepts::check<Geometry>();
186
187 dispatch::assign
188 <
189 typename tag<Geometry>::type,
190 Geometry,
191 geometry::dimension<Geometry>::type::value
192 >::apply(geometry, c1, c2, c3);
193 }
194
195 /*!
196 \brief Assign four values to a geometry (usually a box or segment)
197 \ingroup assign
198 \tparam Geometry \tparam_geometry
199 \tparam Type \tparam_numeric to specify the coordinates
200 \param geometry \param_geometry
201 \param c1 First coordinate (usually x1)
202 \param c2 Second coordinate (usually y1)
203 \param c3 Third coordinate (usually x2)
204 \param c4 Fourth coordinate (usually y2)
205
206 \qbk{distinguish, 4 coordinate values}
207 */
208 template <typename Geometry, typename Type>
209 inline void assign_values(Geometry& geometry,
210 Type const& c1, Type const& c2, Type const& c3, Type const& c4)
211 {
212 concepts::check<Geometry>();
213
214 dispatch::assign
215 <
216 typename tag<Geometry>::type,
217 Geometry,
218 geometry::dimension<Geometry>::type::value
219 >::apply(geometry, c1, c2, c3, c4);
220 }
221
222
223
224 namespace resolve_variant
225 {
226
227 template <typename Geometry1, typename Geometry2>
228 struct assign
229 {
230 static inline void
231 apply(Geometry1& geometry1, const Geometry2& geometry2)
232 {
233 concepts::check<Geometry1>();
234 concepts::check<Geometry2 const>();
235 concepts::check_concepts_and_equal_dimensions<Geometry1, Geometry2 const>();
236
237 static bool const same_point_order
238 = point_order<Geometry1>::value == point_order<Geometry2>::value;
239 BOOST_GEOMETRY_STATIC_ASSERT(
240 same_point_order,
241 "Assign is not supported for different point orders.",
242 Geometry1, Geometry2);
243 static bool const same_closure
244 = closure<Geometry1>::value == closure<Geometry2>::value;
245 BOOST_GEOMETRY_STATIC_ASSERT(
246 same_closure,
247 "Assign is not supported for different closures.",
248 Geometry1, Geometry2);
249
250 dispatch::convert<Geometry2, Geometry1>::apply(geometry2, geometry1);
251 }
252 };
253
254
255 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
256 struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
257 {
258 struct visitor: static_visitor<void>
259 {
260 Geometry2 const& m_geometry2;
261
262 visitor(Geometry2 const& geometry2)
263 : m_geometry2(geometry2)
264 {}
265
266 template <typename Geometry1>
267 result_type operator()(Geometry1& geometry1) const
268 {
269 return assign
270 <
271 Geometry1,
272 Geometry2
273 >::apply
274 (geometry1, m_geometry2);
275 }
276 };
277
278 static inline void
279 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry1,
280 Geometry2 const& geometry2)
281 {
282 return boost::apply_visitor(visitor(geometry2), geometry1);
283 }
284 };
285
286
287 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
288 struct assign<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
289 {
290 struct visitor: static_visitor<void>
291 {
292 Geometry1& m_geometry1;
293
294 visitor(Geometry1 const& geometry1)
295 : m_geometry1(geometry1)
296 {}
297
298 template <typename Geometry2>
299 result_type operator()(Geometry2 const& geometry2) const
300 {
301 return assign
302 <
303 Geometry1,
304 Geometry2
305 >::apply
306 (m_geometry1, geometry2);
307 }
308 };
309
310 static inline void
311 apply(Geometry1& geometry1,
312 variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
313 {
314 return boost::apply_visitor(visitor(geometry1), geometry2);
315 }
316 };
317
318
319 template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
320 struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
321 {
322 struct visitor: static_visitor<void>
323 {
324 template <typename Geometry1, typename Geometry2>
325 result_type operator()(
326 Geometry1& geometry1,
327 Geometry2 const& geometry2) const
328 {
329 return assign
330 <
331 Geometry1,
332 Geometry2
333 >::apply
334 (geometry1, geometry2);
335 }
336 };
337
338 static inline void
339 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
340 variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
341 {
342 return boost::apply_visitor(visitor(), geometry1, geometry2);
343 }
344 };
345
346 } // namespace resolve_variant
347
348
349 /*!
350 \brief Assigns one geometry to another geometry
351 \details The assign algorithm assigns one geometry, e.g. a BOX, to another
352 geometry, e.g. a RING. This only works if it is possible and applicable.
353 \ingroup assign
354 \tparam Geometry1 \tparam_geometry
355 \tparam Geometry2 \tparam_geometry
356 \param geometry1 \param_geometry (target)
357 \param geometry2 \param_geometry (source)
358
359 \qbk{
360 [heading Example]
361 [assign] [assign_output]
362
363 [heading See also]
364 \* [link geometry.reference.algorithms.convert convert]
365 }
366 */
367 template <typename Geometry1, typename Geometry2>
368 inline void assign(Geometry1& geometry1, Geometry2 const& geometry2)
369 {
370 resolve_variant::assign<Geometry1, Geometry2>::apply(geometry1, geometry2);
371 }
372
373
374 }} // namespace boost::geometry
375
376
377
378 #endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP