1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
8 // This file was modified by Oracle on 2014.
9 // Modifications copyright (c) 2014, Oracle and/or its affiliates.
11 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
20 #ifndef BOOST_GEOMETRY_GEOMETRIES_POINT_HPP
21 #define BOOST_GEOMETRY_GEOMETRIES_POINT_HPP
25 #include <boost/config.hpp>
26 #include <boost/mpl/assert.hpp>
27 #include <boost/mpl/int.hpp>
29 #include <boost/geometry/core/access.hpp>
30 #include <boost/geometry/core/assert.hpp>
31 #include <boost/geometry/core/coordinate_type.hpp>
32 #include <boost/geometry/core/coordinate_system.hpp>
33 #include <boost/geometry/core/coordinate_dimension.hpp>
35 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
37 #include <boost/geometry/core/assert.hpp>
40 namespace boost { namespace geometry
43 // Silence warning C4127: conditional expression is constant
46 #pragma warning(disable : 4127)
56 template <std::size_t DimensionCount, std::size_t Index>
60 static inline void apply(T values[], T const& value)
62 values[Index] = value;
66 // Specialization avoiding assigning element [2] for only 2 dimensions
67 template <> struct array_assign<2, 2>
69 template <typename T> static inline void apply(T [], T const& ) {}
72 // Specialization avoiding assigning elements for (rarely used) points in 1 dim
73 template <> struct array_assign<1, 1>
75 template <typename T> static inline void apply(T [], T const& ) {}
78 template <> struct array_assign<1, 2>
80 template <typename T> static inline void apply(T [], T const& ) {}
85 \brief Basic point class, having coordinates defined in a neutral way
86 \details Defines a neutral point class, fulfilling the Point Concept.
87 Library users can use this point class, or use their own point classes.
88 This point class is used in most of the samples and tests of Boost.Geometry
89 This point class is used occasionally within the library, where a temporary
90 point class is necessary.
92 \tparam CoordinateType \tparam_numeric
93 \tparam DimensionCount number of coordinates, usually 2 or 3
94 \tparam CoordinateSystem coordinate system, for example cs::cartesian
96 \qbk{[include reference/geometries/point.qbk]}
97 \qbk{before.synopsis, [heading Model of]}
98 \qbk{before.synopsis, [link geometry.reference.concepts.concept_point Point Concept]}
104 typename CoordinateType,
105 std::size_t DimensionCount,
106 typename CoordinateSystem
110 BOOST_MPL_ASSERT_MSG((DimensionCount >= 1),
111 DIMENSION_GREATER_THAN_ZERO_EXPECTED,
112 (boost::mpl::int_<DimensionCount>));
114 // The following enum is used to fully instantiate the
115 // CoordinateSystem class and check the correctness of the units
116 // passed for non-Cartesian coordinate systems.
117 enum { cs_check = sizeof(CoordinateSystem) };
121 #if !defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
122 #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
123 /// \constructor_default_no_init
126 /// \constructor_default_no_init
130 #else // defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
134 std::fill_n(m_values_initialized, DimensionCount, 0);
139 std::fill_n(m_values_initialized, DimensionCount, 0);
143 /// @brief Constructor to set one value
144 explicit inline point(CoordinateType const& v0)
146 detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
147 detail::array_assign<DimensionCount, 1>::apply(m_values, CoordinateType());
148 detail::array_assign<DimensionCount, 2>::apply(m_values, CoordinateType());
150 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
152 std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
156 /// @brief Constructor to set two values
157 inline point(CoordinateType const& v0, CoordinateType const& v1)
159 detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
160 detail::array_assign<DimensionCount, 1>::apply(m_values, v1);
161 detail::array_assign<DimensionCount, 2>::apply(m_values, CoordinateType());
163 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
165 std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
169 /// @brief Constructor to set three values
170 inline point(CoordinateType const& v0, CoordinateType const& v1,
171 CoordinateType const& v2)
173 detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
174 detail::array_assign<DimensionCount, 1>::apply(m_values, v1);
175 detail::array_assign<DimensionCount, 2>::apply(m_values, v2);
177 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
179 std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
183 /// @brief Get a coordinate
184 /// @tparam K coordinate to get
185 /// @return the coordinate
186 template <std::size_t K>
187 inline CoordinateType const& get() const
189 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
190 BOOST_GEOMETRY_ASSERT(m_created == 1);
191 BOOST_GEOMETRY_ASSERT(m_values_initialized[K] == 1);
193 BOOST_STATIC_ASSERT(K < DimensionCount);
197 /// @brief Set a coordinate
198 /// @tparam K coordinate to set
199 /// @param value value to set
200 template <std::size_t K>
201 inline void set(CoordinateType const& value)
203 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
204 BOOST_GEOMETRY_ASSERT(m_created == 1);
205 m_values_initialized[K] = 1;
207 BOOST_STATIC_ASSERT(K < DimensionCount);
213 CoordinateType m_values[DimensionCount];
215 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
217 int m_values_initialized[DimensionCount];
224 // Adapt the point to the concept
225 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
230 typename CoordinateType,
231 std::size_t DimensionCount,
232 typename CoordinateSystem
234 struct tag<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
236 typedef point_tag type;
241 typename CoordinateType,
242 std::size_t DimensionCount,
243 typename CoordinateSystem
245 struct coordinate_type<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
247 typedef CoordinateType type;
252 typename CoordinateType,
253 std::size_t DimensionCount,
254 typename CoordinateSystem
256 struct coordinate_system<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
258 typedef CoordinateSystem type;
263 typename CoordinateType,
264 std::size_t DimensionCount,
265 typename CoordinateSystem
267 struct dimension<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
268 : boost::mpl::int_<DimensionCount>
273 typename CoordinateType,
274 std::size_t DimensionCount,
275 typename CoordinateSystem,
276 std::size_t Dimension
278 struct access<model::point<CoordinateType, DimensionCount, CoordinateSystem>, Dimension>
280 static inline CoordinateType get(
281 model::point<CoordinateType, DimensionCount, CoordinateSystem> const& p)
283 return p.template get<Dimension>();
286 static inline void set(
287 model::point<CoordinateType, DimensionCount, CoordinateSystem>& p,
288 CoordinateType const& value)
290 p.template set<Dimension>(value);
294 } // namespace traits
295 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
297 #if defined(_MSC_VER)
301 }} // namespace boost::geometry
303 #endif // BOOST_GEOMETRY_GEOMETRIES_POINT_HPP