]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/geometries/segment.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / geometries / segment.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
7 // This file was modified by Oracle on 2020.
8 // Modifications copyright (c) 2020, Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
11 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
12 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
13
14 // Use, modification and distribution is subject to the Boost Software License,
15 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
16 // http://www.boost.org/LICENSE_1_0.txt)
17
18 #ifndef BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP
19 #define BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP
20
21 #include <cstddef>
22 #include <utility>
23 #include <type_traits>
24
25 #include <boost/concept/assert.hpp>
26
27 #include <boost/geometry/core/access.hpp>
28 #include <boost/geometry/core/make.hpp>
29 #include <boost/geometry/core/point_type.hpp>
30 #include <boost/geometry/core/tag.hpp>
31 #include <boost/geometry/core/tags.hpp>
32
33 #include <boost/geometry/geometries/concepts/point_concept.hpp>
34
35 namespace boost { namespace geometry
36 {
37
38 namespace model
39 {
40
41 /*!
42 \brief Class segment: small class containing two points
43 \ingroup geometries
44 \details From Wikipedia: In geometry, a line segment is a part of a line that is bounded
45 by two distinct end points, and contains every point on the line between its end points.
46 \note There is also a point-referring-segment, class referring_segment,
47 containing point references, where points are NOT copied
48
49 \qbk{[include reference/geometries/segment.qbk]}
50 \qbk{before.synopsis,
51 [heading Model of]
52 [link geometry.reference.concepts.concept_segment Segment Concept]
53 }
54 */
55 template<typename Point>
56 class segment : public std::pair<Point, Point>
57 {
58 BOOST_CONCEPT_ASSERT( (concepts::Point<Point>) );
59
60 public :
61
62 /// \constructor_default_no_init
63 constexpr segment() = default;
64
65 /*!
66 \brief Constructor taking the first and the second point
67 */
68 constexpr segment(Point const& p1, Point const& p2)
69 : std::pair<Point, Point>(p1, p2)
70 {}
71 };
72
73
74 /*!
75 \brief Class segment: small class containing two (templatized) point references
76 \ingroup geometries
77 \details From Wikipedia: In geometry, a line segment is a part of a line that is bounded
78 by two distinct end points, and contains every point on the line between its end points.
79 \note The structure is like std::pair, and can often be used interchangeable.
80 Difference is that it refers to points, does not have points.
81 \note Like std::pair, points are public available.
82 \note type is const or non const, so geometry::segment<P> or geometry::segment<P const>
83 \note We cannot derive from std::pair<P&, P&> because of
84 reference assignments.
85 \tparam ConstOrNonConstPoint point type of the segment, maybe a point or a const point
86 */
87 template<typename ConstOrNonConstPoint>
88 class referring_segment
89 {
90 BOOST_CONCEPT_ASSERT( (
91 typename std::conditional
92 <
93 std::is_const<ConstOrNonConstPoint>::value,
94 concepts::Point<ConstOrNonConstPoint>,
95 concepts::ConstPoint<ConstOrNonConstPoint>
96 >
97 ) );
98
99 typedef ConstOrNonConstPoint point_type;
100
101 public:
102
103 point_type& first;
104 point_type& second;
105
106 /*!
107 \brief Constructor taking the first and the second point
108 */
109 inline referring_segment(point_type& p1, point_type& p2)
110 : first(p1)
111 , second(p2)
112 {}
113 };
114
115
116 } // namespace model
117
118
119 // Traits specializations for segment above
120 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
121 namespace traits
122 {
123
124 template <typename Point>
125 struct tag<model::segment<Point> >
126 {
127 typedef segment_tag type;
128 };
129
130 template <typename Point>
131 struct point_type<model::segment<Point> >
132 {
133 typedef Point type;
134 };
135
136 template <typename Point, std::size_t Dimension>
137 struct indexed_access<model::segment<Point>, 0, Dimension>
138 {
139 typedef model::segment<Point> segment_type;
140 typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
141
142 static constexpr coordinate_type get(segment_type const& s)
143 {
144 return geometry::get<Dimension>(s.first);
145 }
146
147 static void set(segment_type& s, coordinate_type const& value)
148 {
149 geometry::set<Dimension>(s.first, value);
150 }
151 };
152
153
154 template <typename Point, std::size_t Dimension>
155 struct indexed_access<model::segment<Point>, 1, Dimension>
156 {
157 typedef model::segment<Point> segment_type;
158 typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
159
160 static constexpr coordinate_type get(segment_type const& s)
161 {
162 return geometry::get<Dimension>(s.second);
163 }
164
165 static void set(segment_type& s, coordinate_type const& value)
166 {
167 geometry::set<Dimension>(s.second, value);
168 }
169 };
170
171
172 template <typename Point>
173 struct make<model::segment<Point> >
174 {
175 typedef model::segment<Point> segment_type;
176
177 static const bool is_specialized = true;
178
179 static constexpr segment_type apply(Point const& p1, Point const& p2)
180 {
181 return segment_type(p1, p2);
182 }
183 };
184
185
186
187 template <typename ConstOrNonConstPoint>
188 struct tag<model::referring_segment<ConstOrNonConstPoint> >
189 {
190 typedef segment_tag type;
191 };
192
193 template <typename ConstOrNonConstPoint>
194 struct point_type<model::referring_segment<ConstOrNonConstPoint> >
195 {
196 typedef ConstOrNonConstPoint type;
197 };
198
199 template <typename ConstOrNonConstPoint, std::size_t Dimension>
200 struct indexed_access<model::referring_segment<ConstOrNonConstPoint>, 0, Dimension>
201 {
202 typedef model::referring_segment<ConstOrNonConstPoint> segment_type;
203 typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
204
205 static inline coordinate_type get(segment_type const& s)
206 {
207 return geometry::get<Dimension>(s.first);
208 }
209
210 static inline void set(segment_type& s, coordinate_type const& value)
211 {
212 geometry::set<Dimension>(s.first, value);
213 }
214 };
215
216
217 template <typename ConstOrNonConstPoint, std::size_t Dimension>
218 struct indexed_access<model::referring_segment<ConstOrNonConstPoint>, 1, Dimension>
219 {
220 typedef model::referring_segment<ConstOrNonConstPoint> segment_type;
221 typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
222
223 static inline coordinate_type get(segment_type const& s)
224 {
225 return geometry::get<Dimension>(s.second);
226 }
227
228 static inline void set(segment_type& s, coordinate_type const& value)
229 {
230 geometry::set<Dimension>(s.second, value);
231 }
232 };
233
234
235
236 } // namespace traits
237 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
238
239 }} // namespace boost::geometry
240
241 #endif // BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP