1// Boost.Geometry (aka GGL, Generic Geometry Library)
2//
3// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
4// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
5// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
6
7// This file was modified by Oracle on 2014.
8// Modifications copyright (c) 2014, Oracle and/or its affiliates.
9
10// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
11
12// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
14
15// Use, modification and distribution is subject to the Boost Software License,
16// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17// http://www.boost.org/LICENSE_1_0.txt)
18
19#ifndef BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POINT_CONCEPT_HPP
20#define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POINT_CONCEPT_HPP
21
22#include <cstddef>
23
24#include <boost/concept_check.hpp>
25#include <boost/core/ignore_unused.hpp>
26
27#include <boost/geometry/core/access.hpp>
28#include <boost/geometry/core/coordinate_dimension.hpp>
29#include <boost/geometry/core/coordinate_system.hpp>
30
31
32
33namespace boost { namespace geometry { namespace concept
34{
35
36/*!
37\brief Point concept.
38\ingroup concepts
39
40\par Formal definition:
41The point concept is defined as following:
42- there must be a specialization of traits::tag defining point_tag as type
43- there must be a specialization of traits::coordinate_type defining the type
44 of its coordinates
45- there must be a specialization of traits::coordinate_system defining its
46 coordinate system (cartesian, spherical, etc)
47- there must be a specialization of traits::dimension defining its number
48 of dimensions (2, 3, ...) (derive it conveniently
49 from boost::mpl::int_&lt;X&gt; for X-D)
50- there must be a specialization of traits::access, per dimension,
51 with two functions:
52 - \b get to get a coordinate value
53 - \b set to set a coordinate value (this one is not checked for ConstPoint)
54- for non-Cartesian coordinate systems, the coordinate system's units
55 must either be boost::geometry::degree or boost::geometry::radian
56
57
58\par Example:
59
60A legacy point, defining the necessary specializations to fulfil to the concept.
61
62Suppose that the following point is defined:
63\dontinclude doxygen_5.cpp
64\skip legacy_point1
65\until };
66
67It can then be adapted to the concept as following:
68\dontinclude doxygen_5.cpp
69\skip adapt legacy_point1
70\until }}
71
72Note that it is done like above to show the system. Users will normally use the registration macro.
73
74\par Example:
75
76A read-only legacy point, using a macro to fulfil to the ConstPoint concept.
77It cannot be modified by the library but can be used in all algorithms where
78points are not modified.
79
80The point looks like the following:
81
82\dontinclude doxygen_5.cpp
83\skip legacy_point2
84\until };
85
86It uses the macro as following:
87\dontinclude doxygen_5.cpp
88\skip adapt legacy_point2
89\until end adaptation
90
91*/
92
93template <typename Geometry>
94class Point
95{
96#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
97
98 typedef typename coordinate_type<Geometry>::type ctype;
99 typedef typename coordinate_system<Geometry>::type csystem;
100
101 // The following enum is used to fully instantiate the coordinate
102 // system class; this is needed in order to check the units passed
103 // to it for non-Cartesian coordinate systems.
104 enum { cs_check = sizeof(csystem) };
105
106 enum { ccount = dimension<Geometry>::value };
107
108 template <typename P, std::size_t Dimension, std::size_t DimensionCount>
109 struct dimension_checker
110 {
111 static void apply()
112 {
113 P* p = 0;
114 geometry::set<Dimension>(*p, geometry::get<Dimension>(*p));
115 dimension_checker<P, Dimension+1, DimensionCount>::apply();
116 }
117 };
118
119
120 template <typename P, std::size_t DimensionCount>
121 struct dimension_checker<P, DimensionCount, DimensionCount>
122 {
123 static void apply() {}
124 };
125
126public:
127
128 /// BCCL macro to apply the Point concept
129 BOOST_CONCEPT_USAGE(Point)
130 {
131 dimension_checker<Geometry, 0, ccount>::apply();
132 }
133#endif
134};
135
136
137/*!
138\brief point concept (const version).
139
140\ingroup const_concepts
141
142\details The ConstPoint concept apply the same as the Point concept,
143but does not apply write access.
144
145*/
146template <typename Geometry>
147class ConstPoint
148{
149#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
150
151 typedef typename coordinate_type<Geometry>::type ctype;
152 typedef typename coordinate_system<Geometry>::type csystem;
153
154 // The following enum is used to fully instantiate the coordinate
155 // system class; this is needed in order to check the units passed
156 // to it for non-Cartesian coordinate systems.
157 enum { cs_check = sizeof(csystem) };
158
159 enum { ccount = dimension<Geometry>::value };
160
161 template <typename P, std::size_t Dimension, std::size_t DimensionCount>
162 struct dimension_checker
163 {
164 static void apply()
165 {
166 const P* p = 0;
167 ctype coord(geometry::get<Dimension>(*p));
168 boost::ignore_unused(p, coord);
169 dimension_checker<P, Dimension+1, DimensionCount>::apply();
170 }
171 };
172
173
174 template <typename P, std::size_t DimensionCount>
175 struct dimension_checker<P, DimensionCount, DimensionCount>
176 {
177 static void apply() {}
178 };
179
180public:
181
182 /// BCCL macro to apply the ConstPoint concept
183 BOOST_CONCEPT_USAGE(ConstPoint)
184 {
185 dimension_checker<Geometry, 0, ccount>::apply();
186 }
187#endif
188};
189
190}}} // namespace boost::geometry::concept
191
192#endif // BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POINT_CONCEPT_HPP
193