]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | ||
3 | // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. | |
4 | // Copyright (c) 2008-2014 Bruno Lalande, Paris, France. | |
5 | // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. | |
6 | // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. | |
7 | ||
20effc67 TL |
8 | // This file was modified by Oracle on 2014-2020. |
9 | // Modifications copyright (c) 2014-2020, Oracle and/or its affiliates. | |
7c673cae | 10 | // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle |
20effc67 | 11 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle |
7c673cae FG |
12 | |
13 | // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library | |
14 | // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. | |
15 | ||
16 | // Use, modification and distribution is subject to the Boost Software License, | |
17 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
18 | // http://www.boost.org/LICENSE_1_0.txt) | |
19 | ||
20 | #ifndef BOOST_GEOMETRY_GEOMETRIES_POINT_HPP | |
21 | #define BOOST_GEOMETRY_GEOMETRIES_POINT_HPP | |
22 | ||
23 | #include <cstddef> | |
20effc67 | 24 | #include <type_traits> |
7c673cae | 25 | |
20effc67 | 26 | #include <boost/static_assert.hpp> |
7c673cae FG |
27 | |
28 | #include <boost/geometry/core/access.hpp> | |
29 | #include <boost/geometry/core/assert.hpp> | |
30 | #include <boost/geometry/core/coordinate_type.hpp> | |
31 | #include <boost/geometry/core/coordinate_system.hpp> | |
32 | #include <boost/geometry/core/coordinate_dimension.hpp> | |
20effc67 TL |
33 | #include <boost/geometry/core/make.hpp> |
34 | #include <boost/geometry/core/tag.hpp> | |
35 | #include <boost/geometry/core/tags.hpp> | |
7c673cae FG |
36 | |
37 | #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) | |
38 | #include <algorithm> | |
39 | #include <boost/geometry/core/assert.hpp> | |
40 | #endif | |
41 | ||
42 | namespace boost { namespace geometry | |
43 | { | |
44 | ||
45 | // Silence warning C4127: conditional expression is constant | |
46 | #if defined(_MSC_VER) | |
47 | #pragma warning(push) | |
48 | #pragma warning(disable : 4127) | |
49 | #endif | |
50 | ||
7c673cae FG |
51 | namespace detail |
52 | { | |
53 | ||
20effc67 TL |
54 | template <typename Dummy, std::size_t N, std::size_t DimensionCount> |
55 | struct is_coordinates_number_leq | |
7c673cae | 56 | { |
20effc67 | 57 | static const bool value = (N <= DimensionCount); |
7c673cae FG |
58 | }; |
59 | ||
20effc67 TL |
60 | template <typename Dummy, std::size_t N, std::size_t DimensionCount> |
61 | struct is_coordinates_number_eq | |
7c673cae | 62 | { |
20effc67 | 63 | static const bool value = (N == DimensionCount); |
7c673cae FG |
64 | }; |
65 | ||
20effc67 | 66 | } // namespace detail |
7c673cae | 67 | |
20effc67 TL |
68 | |
69 | namespace model | |
7c673cae | 70 | { |
7c673cae | 71 | |
7c673cae FG |
72 | /*! |
73 | \brief Basic point class, having coordinates defined in a neutral way | |
74 | \details Defines a neutral point class, fulfilling the Point Concept. | |
75 | Library users can use this point class, or use their own point classes. | |
76 | This point class is used in most of the samples and tests of Boost.Geometry | |
77 | This point class is used occasionally within the library, where a temporary | |
78 | point class is necessary. | |
79 | \ingroup geometries | |
80 | \tparam CoordinateType \tparam_numeric | |
81 | \tparam DimensionCount number of coordinates, usually 2 or 3 | |
82 | \tparam CoordinateSystem coordinate system, for example cs::cartesian | |
83 | ||
84 | \qbk{[include reference/geometries/point.qbk]} | |
85 | \qbk{before.synopsis, [heading Model of]} | |
86 | \qbk{before.synopsis, [link geometry.reference.concepts.concept_point Point Concept]} | |
87 | ||
88 | ||
89 | */ | |
90 | template | |
91 | < | |
92 | typename CoordinateType, | |
93 | std::size_t DimensionCount, | |
94 | typename CoordinateSystem | |
95 | > | |
96 | class point | |
97 | { | |
20effc67 | 98 | BOOST_STATIC_ASSERT(DimensionCount > 0); |
7c673cae FG |
99 | |
100 | // The following enum is used to fully instantiate the | |
101 | // CoordinateSystem class and check the correctness of the units | |
102 | // passed for non-Cartesian coordinate systems. | |
103 | enum { cs_check = sizeof(CoordinateSystem) }; | |
104 | ||
105 | public: | |
106 | ||
20effc67 TL |
107 | // TODO: constexpr requires LiteralType and until C++20 |
108 | // it has to have trivial destructor which makes access | |
109 | // debugging impossible with constexpr. | |
110 | ||
7c673cae | 111 | #if !defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) |
7c673cae | 112 | /// \constructor_default_no_init |
20effc67 TL |
113 | constexpr point() |
114 | // Workaround for VS2015 | |
115 | #if defined(_MSC_VER) && (_MSC_VER < 1910) | |
116 | : m_values{} {} | |
7c673cae | 117 | #else |
20effc67 | 118 | = default; |
7c673cae FG |
119 | #endif |
120 | #else // defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) | |
121 | point() | |
122 | { | |
123 | m_created = 1; | |
124 | std::fill_n(m_values_initialized, DimensionCount, 0); | |
125 | } | |
126 | ~point() | |
127 | { | |
128 | m_created = 0; | |
129 | std::fill_n(m_values_initialized, DimensionCount, 0); | |
130 | } | |
131 | #endif | |
132 | ||
133 | /// @brief Constructor to set one value | |
20effc67 TL |
134 | template |
135 | < | |
136 | typename C = CoordinateType, | |
137 | std::enable_if_t<geometry::detail::is_coordinates_number_leq<C, 1, DimensionCount>::value, int> = 0 | |
138 | > | |
139 | #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) | |
140 | constexpr | |
141 | #endif | |
142 | explicit point(CoordinateType const& v0) | |
143 | : m_values{v0} | |
7c673cae | 144 | { |
7c673cae FG |
145 | #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) |
146 | m_created = 1; | |
20effc67 | 147 | std::fill_n(m_values_initialized, DimensionCount, 1); |
7c673cae FG |
148 | #endif |
149 | } | |
150 | ||
151 | /// @brief Constructor to set two values | |
20effc67 TL |
152 | template |
153 | < | |
154 | typename C = CoordinateType, | |
155 | std::enable_if_t<geometry::detail::is_coordinates_number_leq<C, 2, DimensionCount>::value, int> = 0 | |
156 | > | |
157 | #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) | |
158 | constexpr | |
159 | #endif | |
160 | point(CoordinateType const& v0, CoordinateType const& v1) | |
161 | : m_values{ v0, v1 } | |
7c673cae | 162 | { |
7c673cae FG |
163 | #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) |
164 | m_created = 1; | |
20effc67 | 165 | std::fill_n(m_values_initialized, DimensionCount, 1); |
7c673cae FG |
166 | #endif |
167 | } | |
168 | ||
169 | /// @brief Constructor to set three values | |
20effc67 TL |
170 | template |
171 | < | |
172 | typename C = CoordinateType, | |
173 | std::enable_if_t<geometry::detail::is_coordinates_number_leq<C, 3, DimensionCount>::value, int> = 0 | |
174 | > | |
175 | #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) | |
176 | constexpr | |
177 | #endif | |
178 | point(CoordinateType const& v0, CoordinateType const& v1, CoordinateType const& v2) | |
179 | : m_values{ v0, v1, v2 } | |
7c673cae | 180 | { |
7c673cae FG |
181 | #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) |
182 | m_created = 1; | |
20effc67 | 183 | std::fill_n(m_values_initialized, DimensionCount, 1); |
7c673cae FG |
184 | #endif |
185 | } | |
186 | ||
187 | /// @brief Get a coordinate | |
188 | /// @tparam K coordinate to get | |
189 | /// @return the coordinate | |
190 | template <std::size_t K> | |
20effc67 TL |
191 | #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) |
192 | constexpr | |
193 | #endif | |
194 | CoordinateType const& get() const | |
7c673cae FG |
195 | { |
196 | #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) | |
197 | BOOST_GEOMETRY_ASSERT(m_created == 1); | |
198 | BOOST_GEOMETRY_ASSERT(m_values_initialized[K] == 1); | |
199 | #endif | |
200 | BOOST_STATIC_ASSERT(K < DimensionCount); | |
201 | return m_values[K]; | |
202 | } | |
203 | ||
204 | /// @brief Set a coordinate | |
205 | /// @tparam K coordinate to set | |
206 | /// @param value value to set | |
207 | template <std::size_t K> | |
20effc67 | 208 | void set(CoordinateType const& value) |
7c673cae FG |
209 | { |
210 | #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) | |
211 | BOOST_GEOMETRY_ASSERT(m_created == 1); | |
212 | m_values_initialized[K] = 1; | |
213 | #endif | |
214 | BOOST_STATIC_ASSERT(K < DimensionCount); | |
215 | m_values[K] = value; | |
216 | } | |
217 | ||
218 | private: | |
219 | ||
220 | CoordinateType m_values[DimensionCount]; | |
221 | ||
222 | #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) | |
223 | int m_created; | |
224 | int m_values_initialized[DimensionCount]; | |
225 | #endif | |
226 | }; | |
227 | ||
228 | ||
229 | } // namespace model | |
230 | ||
231 | // Adapt the point to the concept | |
232 | #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS | |
233 | namespace traits | |
234 | { | |
235 | template | |
236 | < | |
237 | typename CoordinateType, | |
238 | std::size_t DimensionCount, | |
239 | typename CoordinateSystem | |
240 | > | |
241 | struct tag<model::point<CoordinateType, DimensionCount, CoordinateSystem> > | |
242 | { | |
243 | typedef point_tag type; | |
244 | }; | |
245 | ||
246 | template | |
247 | < | |
248 | typename CoordinateType, | |
249 | std::size_t DimensionCount, | |
250 | typename CoordinateSystem | |
251 | > | |
252 | struct coordinate_type<model::point<CoordinateType, DimensionCount, CoordinateSystem> > | |
253 | { | |
254 | typedef CoordinateType type; | |
255 | }; | |
256 | ||
257 | template | |
258 | < | |
259 | typename CoordinateType, | |
260 | std::size_t DimensionCount, | |
261 | typename CoordinateSystem | |
262 | > | |
263 | struct coordinate_system<model::point<CoordinateType, DimensionCount, CoordinateSystem> > | |
264 | { | |
265 | typedef CoordinateSystem type; | |
266 | }; | |
267 | ||
268 | template | |
269 | < | |
270 | typename CoordinateType, | |
271 | std::size_t DimensionCount, | |
272 | typename CoordinateSystem | |
273 | > | |
274 | struct dimension<model::point<CoordinateType, DimensionCount, CoordinateSystem> > | |
20effc67 | 275 | : std::integral_constant<std::size_t, DimensionCount> |
7c673cae FG |
276 | {}; |
277 | ||
278 | template | |
279 | < | |
280 | typename CoordinateType, | |
281 | std::size_t DimensionCount, | |
282 | typename CoordinateSystem, | |
283 | std::size_t Dimension | |
284 | > | |
285 | struct access<model::point<CoordinateType, DimensionCount, CoordinateSystem>, Dimension> | |
286 | { | |
20effc67 | 287 | static constexpr CoordinateType get( |
7c673cae FG |
288 | model::point<CoordinateType, DimensionCount, CoordinateSystem> const& p) |
289 | { | |
290 | return p.template get<Dimension>(); | |
291 | } | |
292 | ||
20effc67 | 293 | static void set( |
7c673cae FG |
294 | model::point<CoordinateType, DimensionCount, CoordinateSystem>& p, |
295 | CoordinateType const& value) | |
296 | { | |
297 | p.template set<Dimension>(value); | |
298 | } | |
299 | }; | |
300 | ||
20effc67 TL |
301 | template |
302 | < | |
303 | typename CoordinateType, | |
304 | std::size_t DimensionCount, | |
305 | typename CoordinateSystem | |
306 | > | |
307 | struct make<model::point<CoordinateType, DimensionCount, CoordinateSystem> > | |
308 | { | |
309 | typedef model::point<CoordinateType, DimensionCount, CoordinateSystem> point_type; | |
310 | ||
311 | static const bool is_specialized = true; | |
312 | ||
313 | template | |
314 | < | |
315 | typename C = CoordinateType, | |
316 | std::enable_if_t<geometry::detail::is_coordinates_number_eq<C, 1, DimensionCount>::value, int> = 0 | |
317 | > | |
318 | static constexpr point_type apply(CoordinateType const& v0) | |
319 | { | |
320 | return point_type(v0); | |
321 | } | |
322 | ||
323 | template | |
324 | < | |
325 | typename C = CoordinateType, | |
326 | std::enable_if_t<geometry::detail::is_coordinates_number_eq<C, 2, DimensionCount>::value, int> = 0 | |
327 | > | |
328 | static constexpr point_type apply(CoordinateType const& v0, | |
329 | CoordinateType const& v1) | |
330 | { | |
331 | return point_type(v0, v1); | |
332 | } | |
333 | ||
334 | template | |
335 | < | |
336 | typename C = CoordinateType, | |
337 | std::enable_if_t<geometry::detail::is_coordinates_number_eq<C, 3, DimensionCount>::value, int> = 0 | |
338 | > | |
339 | static constexpr point_type apply(CoordinateType const& v0, | |
340 | CoordinateType const& v1, | |
341 | CoordinateType const& v2) | |
342 | { | |
343 | return point_type(v0, v1, v2); | |
344 | } | |
345 | }; | |
346 | ||
347 | ||
7c673cae FG |
348 | } // namespace traits |
349 | #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS | |
350 | ||
351 | #if defined(_MSC_VER) | |
352 | #pragma warning(pop) | |
353 | #endif | |
354 | ||
355 | }} // namespace boost::geometry | |
356 | ||
357 | #endif // BOOST_GEOMETRY_GEOMETRIES_POINT_HPP |