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