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_GEOMETRIES_SEGMENT_HPP
15#define BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP
16
17#include <cstddef>
18
19#include <boost/concept/assert.hpp>
20#include <boost/mpl/if.hpp>
21#include <boost/type_traits/is_const.hpp>
22
23#include <boost/geometry/geometries/concepts/point_concept.hpp>
24
25namespace boost { namespace geometry
26{
27
28namespace model
29{
30
31/*!
32\brief Class segment: small class containing two points
33\ingroup geometries
34\details From Wikipedia: In geometry, a line segment is a part of a line that is bounded
35 by two distinct end points, and contains every point on the line between its end points.
36\note There is also a point-referring-segment, class referring_segment,
37 containing point references, where points are NOT copied
38
39\qbk{[include reference/geometries/segment.qbk]}
40\qbk{before.synopsis,
41[heading Model of]
42[link geometry.reference.concepts.concept_segment Segment Concept]
43}
44*/
45template<typename Point>
46class segment : public std::pair<Point, Point>
47{
48 BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
49
50public :
51
52#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
53 /// \constructor_default_no_init
54 segment() = default;
55#else
56 /// \constructor_default_no_init
57 inline segment()
58 {}
59#endif
60
61 /*!
62 \brief Constructor taking the first and the second point
63 */
64 inline segment(Point const& p1, Point const& p2)
65 {
66 this->first = p1;
67 this->second = p2;
68 }
69};
70
71
72/*!
73\brief Class segment: small class containing two (templatized) point references
74\ingroup geometries
75\details From Wikipedia: In geometry, a line segment is a part of a line that is bounded
76 by two distinct end points, and contains every point on the line between its end points.
77\note The structure is like std::pair, and can often be used interchangeable.
78Difference is that it refers to points, does not have points.
79\note Like std::pair, points are public available.
80\note type is const or non const, so geometry::segment<P> or geometry::segment<P const>
81\note We cannot derive from std::pair<P&, P&> because of
82reference assignments.
83\tparam ConstOrNonConstPoint point type of the segment, maybe a point or a const point
84*/
85template<typename ConstOrNonConstPoint>
86class referring_segment
87{
88 BOOST_CONCEPT_ASSERT( (
89 typename boost::mpl::if_
90 <
91 boost::is_const<ConstOrNonConstPoint>,
92 concept::Point<ConstOrNonConstPoint>,
93 concept::ConstPoint<ConstOrNonConstPoint>
94 >
95 ) );
96
97 typedef ConstOrNonConstPoint point_type;
98
99public:
100
101 point_type& first;
102 point_type& second;
103
104 /*!
105 \brief Constructor taking the first and the second point
106 */
107 inline referring_segment(point_type& p1, point_type& p2)
108 : first(p1)
109 , second(p2)
110 {}
111};
112
113
114} // namespace model
115
116
117// Traits specializations for segment above
118#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
119namespace traits
120{
121
122template <typename Point>
123struct tag<model::segment<Point> >
124{
125 typedef segment_tag type;
126};
127
128template <typename Point>
129struct point_type<model::segment<Point> >
130{
131 typedef Point type;
132};
133
134template <typename Point, std::size_t Dimension>
135struct indexed_access<model::segment<Point>, 0, Dimension>
136{
137 typedef model::segment<Point> segment_type;
138 typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
139
140 static inline coordinate_type get(segment_type const& s)
141 {
142 return geometry::get<Dimension>(s.first);
143 }
144
145 static inline void set(segment_type& s, coordinate_type const& value)
146 {
147 geometry::set<Dimension>(s.first, value);
148 }
149};
150
151
152template <typename Point, std::size_t Dimension>
153struct indexed_access<model::segment<Point>, 1, Dimension>
154{
155 typedef model::segment<Point> segment_type;
156 typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
157
158 static inline coordinate_type get(segment_type const& s)
159 {
160 return geometry::get<Dimension>(s.second);
161 }
162
163 static inline void set(segment_type& s, coordinate_type const& value)
164 {
165 geometry::set<Dimension>(s.second, value);
166 }
167};
168
169
170template <typename ConstOrNonConstPoint>
171struct tag<model::referring_segment<ConstOrNonConstPoint> >
172{
173 typedef segment_tag type;
174};
175
176template <typename ConstOrNonConstPoint>
177struct point_type<model::referring_segment<ConstOrNonConstPoint> >
178{
179 typedef ConstOrNonConstPoint type;
180};
181
182template <typename ConstOrNonConstPoint, std::size_t Dimension>
183struct indexed_access<model::referring_segment<ConstOrNonConstPoint>, 0, Dimension>
184{
185 typedef model::referring_segment<ConstOrNonConstPoint> segment_type;
186 typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
187
188 static inline coordinate_type get(segment_type const& s)
189 {
190 return geometry::get<Dimension>(s.first);
191 }
192
193 static inline void set(segment_type& s, coordinate_type const& value)
194 {
195 geometry::set<Dimension>(s.first, value);
196 }
197};
198
199
200template <typename ConstOrNonConstPoint, std::size_t Dimension>
201struct indexed_access<model::referring_segment<ConstOrNonConstPoint>, 1, Dimension>
202{
203 typedef model::referring_segment<ConstOrNonConstPoint> segment_type;
204 typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
205
206 static inline coordinate_type get(segment_type const& s)
207 {
208 return geometry::get<Dimension>(s.second);
209 }
210
211 static inline void set(segment_type& s, coordinate_type const& value)
212 {
213 geometry::set<Dimension>(s.second, value);
214 }
215};
216
217
218
219} // namespace traits
220#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
221
222}} // namespace boost::geometry
223
224#endif // BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP
225

source code of boost/boost/geometry/geometries/segment.hpp