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
7// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
9
10// Use, modification and distribution is subject to the Boost Software License,
11// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12// http://www.boost.org/LICENSE_1_0.txt)
13
14#ifndef BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
15#define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
16
17
18#include <cstddef>
19
20#include <boost/concept/requires.hpp>
21#include <boost/concept_check.hpp>
22#include <boost/mpl/assert.hpp>
23#include <boost/mpl/if.hpp>
24#include <boost/numeric/conversion/bounds.hpp>
25#include <boost/numeric/conversion/cast.hpp>
26#include <boost/type_traits.hpp>
27
28#include <boost/geometry/arithmetic/arithmetic.hpp>
29#include <boost/geometry/algorithms/append.hpp>
30#include <boost/geometry/algorithms/clear.hpp>
31#include <boost/geometry/core/access.hpp>
32#include <boost/geometry/core/exterior_ring.hpp>
33#include <boost/geometry/core/tags.hpp>
34
35#include <boost/geometry/geometries/concepts/check.hpp>
36
37
38#include <boost/geometry/util/for_each_coordinate.hpp>
39
40
41namespace boost { namespace geometry
42{
43
44#ifndef DOXYGEN_NO_DETAIL
45namespace detail { namespace assign
46{
47
48
49template <std::size_t Index, std::size_t Dimension, std::size_t DimensionCount>
50struct initialize
51{
52 template <typename Box>
53 static inline void apply(Box& box, typename coordinate_type<Box>::type const& value)
54 {
55 geometry::set<Index, Dimension>(box, value);
56 initialize<Index, Dimension + 1, DimensionCount>::apply(box, value);
57 }
58};
59
60
61template <std::size_t Index, std::size_t DimensionCount>
62struct initialize<Index, DimensionCount, DimensionCount>
63{
64 template <typename Box>
65 static inline void apply(Box&, typename coordinate_type<Box>::type const&)
66 {}
67};
68
69
70struct assign_zero_point
71{
72 template <typename Point>
73 static inline void apply(Point& point)
74 {
75 geometry::assign_value(point, 0);
76 }
77};
78
79
80struct assign_inverse_box_or_segment
81{
82
83 template <typename BoxOrSegment>
84 static inline void apply(BoxOrSegment& geometry)
85 {
86 typedef typename point_type<BoxOrSegment>::type point_type;
87 typedef typename coordinate_type<point_type>::type bound_type;
88
89 initialize<0, 0, dimension<BoxOrSegment>::type::value>::apply(
90 geometry, boost::numeric::bounds<bound_type>::highest()
91 );
92 initialize<1, 0, dimension<BoxOrSegment>::type::value>::apply(
93 geometry, boost::numeric::bounds<bound_type>::lowest()
94 );
95 }
96};
97
98
99struct assign_zero_box_or_segment
100{
101 template <typename BoxOrSegment>
102 static inline void apply(BoxOrSegment& geometry)
103 {
104 typedef typename coordinate_type<BoxOrSegment>::type coordinate_type;
105
106 initialize<0, 0, dimension<BoxOrSegment>::type::value>::apply(
107 geometry, coordinate_type()
108 );
109 initialize<1, 0, dimension<BoxOrSegment>::type::value>::apply(
110 geometry, coordinate_type()
111 );
112 }
113};
114
115
116template
117<
118 std::size_t Corner1, std::size_t Corner2,
119 typename Box, typename Point
120>
121inline void assign_box_2d_corner(Box const& box, Point& point)
122{
123 // Be sure both are 2-Dimensional
124 assert_dimension<Box, 2>();
125 assert_dimension<Point, 2>();
126
127 // Copy coordinates
128 typedef typename coordinate_type<Point>::type coordinate_type;
129
130 geometry::set<0>(point, boost::numeric_cast<coordinate_type>(get<Corner1, 0>(box)));
131 geometry::set<1>(point, boost::numeric_cast<coordinate_type>(get<Corner2, 1>(box)));
132}
133
134
135
136template
137<
138 typename Geometry, typename Point,
139 std::size_t Index,
140 std::size_t Dimension, std::size_t DimensionCount
141>
142struct assign_point_to_index
143{
144
145 static inline void apply(Point const& point, Geometry& geometry)
146 {
147 geometry::set<Index, Dimension>(geometry, boost::numeric_cast
148 <
149 typename coordinate_type<Geometry>::type
150 >(geometry::get<Dimension>(point)));
151
152 assign_point_to_index
153 <
154 Geometry, Point, Index, Dimension + 1, DimensionCount
155 >::apply(point, geometry);
156 }
157};
158
159template
160<
161 typename Geometry, typename Point,
162 std::size_t Index,
163 std::size_t DimensionCount
164>
165struct assign_point_to_index
166 <
167 Geometry, Point,
168 Index,
169 DimensionCount, DimensionCount
170 >
171{
172 static inline void apply(Point const& , Geometry& )
173 {
174 }
175};
176
177
178template
179<
180 typename Geometry, typename Point,
181 std::size_t Index,
182 std::size_t Dimension, std::size_t DimensionCount
183>
184struct assign_point_from_index
185{
186
187 static inline void apply(Geometry const& geometry, Point& point)
188 {
189 geometry::set<Dimension>( point, boost::numeric_cast
190 <
191 typename coordinate_type<Point>::type
192 >(geometry::get<Index, Dimension>(geometry)));
193
194 assign_point_from_index
195 <
196 Geometry, Point, Index, Dimension + 1, DimensionCount
197 >::apply(geometry, point);
198 }
199};
200
201template
202<
203 typename Geometry, typename Point,
204 std::size_t Index,
205 std::size_t DimensionCount
206>
207struct assign_point_from_index
208 <
209 Geometry, Point,
210 Index,
211 DimensionCount, DimensionCount
212 >
213{
214 static inline void apply(Geometry const&, Point&)
215 {
216 }
217};
218
219
220template <typename Geometry>
221struct assign_2d_box_or_segment
222{
223 typedef typename coordinate_type<Geometry>::type coordinate_type;
224
225 // Here we assign 4 coordinates to a box of segment
226 // -> Most logical is: x1,y1,x2,y2
227 // In case the user reverses x1/x2 or y1/y2, for a box, we could reverse them (THAT IS NOT IMPLEMENTED)
228
229 template <typename Type>
230 static inline void apply(Geometry& geometry,
231 Type const& x1, Type const& y1, Type const& x2, Type const& y2)
232 {
233 geometry::set<0, 0>(geometry, boost::numeric_cast<coordinate_type>(x1));
234 geometry::set<0, 1>(geometry, boost::numeric_cast<coordinate_type>(y1));
235 geometry::set<1, 0>(geometry, boost::numeric_cast<coordinate_type>(x2));
236 geometry::set<1, 1>(geometry, boost::numeric_cast<coordinate_type>(y2));
237 }
238};
239
240
241}} // namespace detail::assign
242#endif // DOXYGEN_NO_DETAIL
243
244#ifndef DOXYGEN_NO_DISPATCH
245namespace dispatch
246{
247
248template <typename GeometryTag, typename Geometry, std::size_t DimensionCount>
249struct assign
250{
251 BOOST_MPL_ASSERT_MSG
252 (
253 false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
254 , (types<Geometry>)
255 );
256};
257
258template <typename Point>
259struct assign<point_tag, Point, 2>
260{
261 typedef typename coordinate_type<Point>::type coordinate_type;
262
263 template <typename T>
264 static inline void apply(Point& point, T const& c1, T const& c2)
265 {
266 set<0>(point, boost::numeric_cast<coordinate_type>(c1));
267 set<1>(point, boost::numeric_cast<coordinate_type>(c2));
268 }
269};
270
271template <typename Point>
272struct assign<point_tag, Point, 3>
273{
274 typedef typename coordinate_type<Point>::type coordinate_type;
275
276 template <typename T>
277 static inline void apply(Point& point, T const& c1, T const& c2, T const& c3)
278 {
279 set<0>(point, boost::numeric_cast<coordinate_type>(c1));
280 set<1>(point, boost::numeric_cast<coordinate_type>(c2));
281 set<2>(point, boost::numeric_cast<coordinate_type>(c3));
282 }
283};
284
285template <typename Box>
286struct assign<box_tag, Box, 2>
287 : detail::assign::assign_2d_box_or_segment<Box>
288{};
289
290template <typename Segment>
291struct assign<segment_tag, Segment, 2>
292 : detail::assign::assign_2d_box_or_segment<Segment>
293{};
294
295
296
297template <typename GeometryTag, typename Geometry>
298struct assign_zero {};
299
300
301template <typename Point>
302struct assign_zero<point_tag, Point>
303 : detail::assign::assign_zero_point
304{};
305
306template <typename Box>
307struct assign_zero<box_tag, Box>
308 : detail::assign::assign_zero_box_or_segment
309{};
310
311template <typename Segment>
312struct assign_zero<segment_tag, Segment>
313 : detail::assign::assign_zero_box_or_segment
314{};
315
316
317template <typename GeometryTag, typename Geometry>
318struct assign_inverse {};
319
320template <typename Box>
321struct assign_inverse<box_tag, Box>
322 : detail::assign::assign_inverse_box_or_segment
323{};
324
325template <typename Segment>
326struct assign_inverse<segment_tag, Segment>
327 : detail::assign::assign_inverse_box_or_segment
328{};
329
330
331} // namespace dispatch
332#endif // DOXYGEN_NO_DISPATCH
333
334}} // namespace boost::geometry
335
336
337#endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
338

source code of boost/boost/geometry/algorithms/detail/assign_values.hpp