]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/include/boost/geometry/algorithms/assign.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / geometry / include / 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 // 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
47 namespace 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 */
69 template <typename Geometry, typename Range>
70 inline 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
82 min corner is very large, the max corner is very small. This is a convenient starting point to
83 collect 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 */
96 template <typename Geometry>
97 inline 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 */
116 template <typename Geometry>
117 inline 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 */
146 template <typename Geometry, typename Type>
147 inline 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 */
178 template <typename Geometry, typename Type>
179 inline 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 */
205 template <typename Geometry, typename Type>
206 inline 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
221 namespace resolve_variant
222 {
223
224 template <typename Geometry1, typename Geometry2>
225 struct 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
256 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
257 struct 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
288 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
289 struct 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
320 template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
321 struct 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
353 geometry, 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 */
368 template <typename Geometry1, typename Geometry2>
369 inline 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