point.hpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
  5. // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
  6. // This file was modified by Oracle on 2014.
  7. // Modifications copyright (c) 2014, Oracle and/or its affiliates.
  8. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  9. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  10. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  11. // Use, modification and distribution is subject to the Boost Software License,
  12. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  13. // http://www.boost.org/LICENSE_1_0.txt)
  14. #ifndef BOOST_GEOMETRY_GEOMETRIES_POINT_HPP
  15. #define BOOST_GEOMETRY_GEOMETRIES_POINT_HPP
  16. #include <cstddef>
  17. #include <boost/config.hpp>
  18. #include <boost/mpl/assert.hpp>
  19. #include <boost/mpl/int.hpp>
  20. #include <boost/geometry/core/access.hpp>
  21. #include <boost/geometry/core/assert.hpp>
  22. #include <boost/geometry/core/coordinate_type.hpp>
  23. #include <boost/geometry/core/coordinate_system.hpp>
  24. #include <boost/geometry/core/coordinate_dimension.hpp>
  25. #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
  26. #include <algorithm>
  27. #include <boost/geometry/core/assert.hpp>
  28. #endif
  29. namespace boost { namespace geometry
  30. {
  31. // Silence warning C4127: conditional expression is constant
  32. #if defined(_MSC_VER)
  33. #pragma warning(push)
  34. #pragma warning(disable : 4127)
  35. #endif
  36. namespace model
  37. {
  38. namespace detail
  39. {
  40. template <std::size_t DimensionCount, std::size_t Index>
  41. struct array_assign
  42. {
  43. template <typename T>
  44. static inline void apply(T values[], T const& value)
  45. {
  46. values[Index] = value;
  47. }
  48. };
  49. // Specialization avoiding assigning element [2] for only 2 dimensions
  50. template <> struct array_assign<2, 2>
  51. {
  52. template <typename T> static inline void apply(T [], T const& ) {}
  53. };
  54. // Specialization avoiding assigning elements for (rarely used) points in 1 dim
  55. template <> struct array_assign<1, 1>
  56. {
  57. template <typename T> static inline void apply(T [], T const& ) {}
  58. };
  59. template <> struct array_assign<1, 2>
  60. {
  61. template <typename T> static inline void apply(T [], T const& ) {}
  62. };
  63. }
  64. /*!
  65. \brief Basic point class, having coordinates defined in a neutral way
  66. \details Defines a neutral point class, fulfilling the Point Concept.
  67. Library users can use this point class, or use their own point classes.
  68. This point class is used in most of the samples and tests of Boost.Geometry
  69. This point class is used occasionally within the library, where a temporary
  70. point class is necessary.
  71. \ingroup geometries
  72. \tparam CoordinateType \tparam_numeric
  73. \tparam DimensionCount number of coordinates, usually 2 or 3
  74. \tparam CoordinateSystem coordinate system, for example cs::cartesian
  75. \qbk{[include reference/geometries/point.qbk]}
  76. \qbk{before.synopsis, [heading Model of]}
  77. \qbk{before.synopsis, [link geometry.reference.concepts.concept_point Point Concept]}
  78. */
  79. template
  80. <
  81. typename CoordinateType,
  82. std::size_t DimensionCount,
  83. typename CoordinateSystem
  84. >
  85. class point
  86. {
  87. BOOST_MPL_ASSERT_MSG((DimensionCount >= 1),
  88. DIMENSION_GREATER_THAN_ZERO_EXPECTED,
  89. (boost::mpl::int_<DimensionCount>));
  90. // The following enum is used to fully instantiate the
  91. // CoordinateSystem class and check the correctness of the units
  92. // passed for non-Cartesian coordinate systems.
  93. enum { cs_check = sizeof(CoordinateSystem) };
  94. public:
  95. #if !defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
  96. #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
  97. /// \constructor_default_no_init
  98. point() = default;
  99. #else
  100. /// \constructor_default_no_init
  101. inline point()
  102. {}
  103. #endif
  104. #else // defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
  105. point()
  106. {
  107. m_created = 1;
  108. std::fill_n(m_values_initialized, DimensionCount, 0);
  109. }
  110. ~point()
  111. {
  112. m_created = 0;
  113. std::fill_n(m_values_initialized, DimensionCount, 0);
  114. }
  115. #endif
  116. /// @brief Constructor to set one value
  117. explicit inline point(CoordinateType const& v0)
  118. {
  119. detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
  120. detail::array_assign<DimensionCount, 1>::apply(m_values, CoordinateType());
  121. detail::array_assign<DimensionCount, 2>::apply(m_values, CoordinateType());
  122. #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
  123. m_created = 1;
  124. std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
  125. #endif
  126. }
  127. /// @brief Constructor to set two values
  128. inline point(CoordinateType const& v0, CoordinateType const& v1)
  129. {
  130. detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
  131. detail::array_assign<DimensionCount, 1>::apply(m_values, v1);
  132. detail::array_assign<DimensionCount, 2>::apply(m_values, CoordinateType());
  133. #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
  134. m_created = 1;
  135. std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
  136. #endif
  137. }
  138. /// @brief Constructor to set three values
  139. inline point(CoordinateType const& v0, CoordinateType const& v1,
  140. CoordinateType const& v2)
  141. {
  142. detail::array_assign<DimensionCount, 0>::apply(m_values, v0);
  143. detail::array_assign<DimensionCount, 1>::apply(m_values, v1);
  144. detail::array_assign<DimensionCount, 2>::apply(m_values, v2);
  145. #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
  146. m_created = 1;
  147. std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1);
  148. #endif
  149. }
  150. /// @brief Get a coordinate
  151. /// @tparam K coordinate to get
  152. /// @return the coordinate
  153. template <std::size_t K>
  154. inline CoordinateType const& get() const
  155. {
  156. #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
  157. BOOST_GEOMETRY_ASSERT(m_created == 1);
  158. BOOST_GEOMETRY_ASSERT(m_values_initialized[K] == 1);
  159. #endif
  160. BOOST_STATIC_ASSERT(K < DimensionCount);
  161. return m_values[K];
  162. }
  163. /// @brief Set a coordinate
  164. /// @tparam K coordinate to set
  165. /// @param value value to set
  166. template <std::size_t K>
  167. inline void set(CoordinateType const& value)
  168. {
  169. #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
  170. BOOST_GEOMETRY_ASSERT(m_created == 1);
  171. m_values_initialized[K] = 1;
  172. #endif
  173. BOOST_STATIC_ASSERT(K < DimensionCount);
  174. m_values[K] = value;
  175. }
  176. private:
  177. CoordinateType m_values[DimensionCount];
  178. #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
  179. int m_created;
  180. int m_values_initialized[DimensionCount];
  181. #endif
  182. };
  183. } // namespace model
  184. // Adapt the point to the concept
  185. #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
  186. namespace traits
  187. {
  188. template
  189. <
  190. typename CoordinateType,
  191. std::size_t DimensionCount,
  192. typename CoordinateSystem
  193. >
  194. struct tag<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
  195. {
  196. typedef point_tag type;
  197. };
  198. template
  199. <
  200. typename CoordinateType,
  201. std::size_t DimensionCount,
  202. typename CoordinateSystem
  203. >
  204. struct coordinate_type<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
  205. {
  206. typedef CoordinateType type;
  207. };
  208. template
  209. <
  210. typename CoordinateType,
  211. std::size_t DimensionCount,
  212. typename CoordinateSystem
  213. >
  214. struct coordinate_system<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
  215. {
  216. typedef CoordinateSystem type;
  217. };
  218. template
  219. <
  220. typename CoordinateType,
  221. std::size_t DimensionCount,
  222. typename CoordinateSystem
  223. >
  224. struct dimension<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
  225. : boost::mpl::int_<DimensionCount>
  226. {};
  227. template
  228. <
  229. typename CoordinateType,
  230. std::size_t DimensionCount,
  231. typename CoordinateSystem,
  232. std::size_t Dimension
  233. >
  234. struct access<model::point<CoordinateType, DimensionCount, CoordinateSystem>, Dimension>
  235. {
  236. static inline CoordinateType get(
  237. model::point<CoordinateType, DimensionCount, CoordinateSystem> const& p)
  238. {
  239. return p.template get<Dimension>();
  240. }
  241. static inline void set(
  242. model::point<CoordinateType, DimensionCount, CoordinateSystem>& p,
  243. CoordinateType const& value)
  244. {
  245. p.template set<Dimension>(value);
  246. }
  247. };
  248. } // namespace traits
  249. #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
  250. #if defined(_MSC_VER)
  251. #pragma warning(pop)
  252. #endif
  253. }} // namespace boost::geometry
  254. #endif // BOOST_GEOMETRY_GEOMETRIES_POINT_HPP