Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:28

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
0006 // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
0007 
0008 // This file was modified by Oracle on 2014-2020.
0009 // Modifications copyright (c) 2014-2020, Oracle and/or its affiliates.
0010 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0011 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0012 
0013 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0014 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0015 
0016 // Use, modification and distribution is subject to the Boost Software License,
0017 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0018 // http://www.boost.org/LICENSE_1_0.txt)
0019 
0020 #ifndef BOOST_GEOMETRY_GEOMETRIES_POINT_HPP
0021 #define BOOST_GEOMETRY_GEOMETRIES_POINT_HPP
0022 
0023 #include <cstddef>
0024 #include <type_traits>
0025 
0026 #include <boost/static_assert.hpp>
0027 
0028 #include <boost/geometry/core/access.hpp>
0029 #include <boost/geometry/core/assert.hpp>
0030 #include <boost/geometry/core/coordinate_type.hpp>
0031 #include <boost/geometry/core/coordinate_system.hpp>
0032 #include <boost/geometry/core/coordinate_dimension.hpp>
0033 #include <boost/geometry/core/make.hpp>
0034 #include <boost/geometry/core/tag.hpp>
0035 #include <boost/geometry/core/tags.hpp>
0036 
0037 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0038 #include <algorithm>
0039 #include <boost/geometry/core/assert.hpp>
0040 #endif
0041 
0042 namespace boost { namespace geometry
0043 {
0044 
0045 // Silence warning C4127: conditional expression is constant
0046 #if defined(_MSC_VER)
0047 #pragma warning(push)
0048 #pragma warning(disable : 4127)
0049 #endif
0050 
0051 namespace detail
0052 {
0053 
0054 template <typename Dummy, std::size_t N, std::size_t DimensionCount>
0055 struct is_coordinates_number_leq
0056 {
0057     static const bool value = (N <= DimensionCount);
0058 };
0059 
0060 template <typename Dummy, std::size_t N, std::size_t DimensionCount>
0061 struct is_coordinates_number_eq
0062 {
0063     static const bool value = (N == DimensionCount);
0064 };
0065 
0066 } // namespace detail
0067 
0068 
0069 namespace model
0070 {
0071 
0072 /*!
0073 \brief Basic point class, having coordinates defined in a neutral way
0074 \details Defines a neutral point class, fulfilling the Point Concept.
0075     Library users can use this point class, or use their own point classes.
0076     This point class is used in most of the samples and tests of Boost.Geometry
0077     This point class is used occasionally within the library, where a temporary
0078     point class is necessary.
0079 \ingroup geometries
0080 \tparam CoordinateType \tparam_numeric
0081 \tparam DimensionCount number of coordinates, usually 2 or 3
0082 \tparam CoordinateSystem coordinate system, for example cs::cartesian
0083 
0084 \qbk{[include reference/geometries/point.qbk]}
0085 \qbk{before.synopsis, [heading Model of]}
0086 \qbk{before.synopsis, [link geometry.reference.concepts.concept_point Point Concept]}
0087 
0088 
0089 */
0090 template
0091 <
0092     typename CoordinateType,
0093     std::size_t DimensionCount,
0094     typename CoordinateSystem
0095 >
0096 class point
0097 {
0098     BOOST_STATIC_ASSERT(DimensionCount > 0);
0099 
0100     // The following enum is used to fully instantiate the
0101     // CoordinateSystem class and check the correctness of the units
0102     // passed for non-Cartesian coordinate systems.
0103     enum { cs_check = sizeof(CoordinateSystem) };
0104 
0105 public:
0106 
0107     // TODO: constexpr requires LiteralType and until C++20
0108     // it has to have trivial destructor which makes access
0109     // debugging impossible with constexpr.
0110 
0111 #if !defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0112     /// \constructor_default_no_init
0113     constexpr point()
0114 // Workaround for VS2015
0115 #if defined(_MSC_VER) && (_MSC_VER < 1910)
0116         : m_values{} {}
0117 #else
0118         = default;
0119 #endif
0120 #else // defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0121     point()
0122     {
0123         m_created = 1;
0124         std::fill_n(m_values_initialized, DimensionCount, 0);
0125     }
0126     ~point()
0127     {
0128         m_created = 0;
0129         std::fill_n(m_values_initialized, DimensionCount, 0);
0130     }
0131 #endif
0132 
0133     /// @brief Constructor to set one value
0134     template
0135     <
0136         typename C = CoordinateType,
0137         std::enable_if_t<geometry::detail::is_coordinates_number_leq<C, 1, DimensionCount>::value, int> = 0
0138     >
0139 #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0140     constexpr
0141 #endif
0142     explicit point(CoordinateType const& v0)
0143         : m_values{v0}
0144     {
0145 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0146         m_created = 1;
0147         std::fill_n(m_values_initialized, DimensionCount, 1);
0148 #endif
0149     }
0150 
0151     /// @brief Constructor to set two values
0152     template
0153     <
0154         typename C = CoordinateType,
0155         std::enable_if_t<geometry::detail::is_coordinates_number_leq<C, 2, DimensionCount>::value, int> = 0
0156     >
0157 #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0158     constexpr
0159 #endif
0160     point(CoordinateType const& v0, CoordinateType const& v1)
0161         : m_values{ v0, v1 }
0162     {
0163 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0164         m_created = 1;
0165         std::fill_n(m_values_initialized, DimensionCount, 1);
0166 #endif
0167     }
0168 
0169     /// @brief Constructor to set three values
0170     template
0171     <
0172         typename C = CoordinateType,
0173         std::enable_if_t<geometry::detail::is_coordinates_number_leq<C, 3, DimensionCount>::value, int> = 0
0174     >
0175 #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0176     constexpr
0177 #endif
0178     point(CoordinateType const& v0, CoordinateType const& v1, CoordinateType const& v2)
0179         : m_values{ v0, v1, v2 }
0180     {
0181 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0182         m_created = 1;
0183         std::fill_n(m_values_initialized, DimensionCount, 1);
0184 #endif
0185     }
0186 
0187     /// @brief Get a coordinate
0188     /// @tparam K coordinate to get
0189     /// @return the coordinate
0190     template <std::size_t K>
0191 #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0192     constexpr
0193 #endif
0194     CoordinateType const& get() const
0195     {
0196 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0197         BOOST_GEOMETRY_ASSERT(m_created == 1);
0198         BOOST_GEOMETRY_ASSERT(m_values_initialized[K] == 1);
0199 #endif
0200         BOOST_STATIC_ASSERT(K < DimensionCount);
0201         return m_values[K];
0202     }
0203 
0204     /// @brief Set a coordinate
0205     /// @tparam K coordinate to set
0206     /// @param value value to set
0207     template <std::size_t K>
0208     void set(CoordinateType const& value)
0209     {
0210 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0211         BOOST_GEOMETRY_ASSERT(m_created == 1);
0212         m_values_initialized[K] = 1;
0213 #endif
0214         BOOST_STATIC_ASSERT(K < DimensionCount);
0215         m_values[K] = value;
0216     }
0217 
0218 private:
0219 
0220     CoordinateType m_values[DimensionCount];
0221 
0222 #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
0223     int m_created;
0224     int m_values_initialized[DimensionCount];
0225 #endif
0226 };
0227 
0228 
0229 } // namespace model
0230 
0231 // Adapt the point to the concept
0232 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
0233 namespace traits
0234 {
0235 template
0236 <
0237     typename CoordinateType,
0238     std::size_t DimensionCount,
0239     typename CoordinateSystem
0240 >
0241 struct tag<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
0242 {
0243     typedef point_tag type;
0244 };
0245 
0246 template
0247 <
0248     typename CoordinateType,
0249     std::size_t DimensionCount,
0250     typename CoordinateSystem
0251 >
0252 struct coordinate_type<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
0253 {
0254     typedef CoordinateType type;
0255 };
0256 
0257 template
0258 <
0259     typename CoordinateType,
0260     std::size_t DimensionCount,
0261     typename CoordinateSystem
0262 >
0263 struct coordinate_system<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
0264 {
0265     typedef CoordinateSystem type;
0266 };
0267 
0268 template
0269 <
0270     typename CoordinateType,
0271     std::size_t DimensionCount,
0272     typename CoordinateSystem
0273 >
0274 struct dimension<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
0275     : std::integral_constant<std::size_t, DimensionCount>
0276 {};
0277 
0278 template
0279 <
0280     typename CoordinateType,
0281     std::size_t DimensionCount,
0282     typename CoordinateSystem,
0283     std::size_t Dimension
0284 >
0285 struct access<model::point<CoordinateType, DimensionCount, CoordinateSystem>, Dimension>
0286 {
0287     static constexpr CoordinateType get(
0288         model::point<CoordinateType, DimensionCount, CoordinateSystem> const& p)
0289     {
0290         return p.template get<Dimension>();
0291     }
0292 
0293     static void set(
0294         model::point<CoordinateType, DimensionCount, CoordinateSystem>& p,
0295         CoordinateType const& value)
0296     {
0297         p.template set<Dimension>(value);
0298     }
0299 };
0300 
0301 template
0302 <
0303     typename CoordinateType,
0304     std::size_t DimensionCount,
0305     typename CoordinateSystem
0306 >
0307 struct make<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
0308 {
0309     typedef model::point<CoordinateType, DimensionCount, CoordinateSystem> point_type;
0310 
0311     static const bool is_specialized = true;
0312 
0313     template
0314     <
0315         typename C = CoordinateType,
0316         std::enable_if_t<geometry::detail::is_coordinates_number_eq<C, 1, DimensionCount>::value, int> = 0
0317     >
0318     static constexpr point_type apply(CoordinateType const& v0)
0319     {
0320         return point_type(v0);
0321     }
0322 
0323     template
0324     <
0325         typename C = CoordinateType,
0326         std::enable_if_t<geometry::detail::is_coordinates_number_eq<C, 2, DimensionCount>::value, int> = 0
0327     >
0328     static constexpr point_type apply(CoordinateType const& v0,
0329                                       CoordinateType const& v1)
0330     {
0331         return point_type(v0, v1);
0332     }
0333 
0334     template
0335     <
0336         typename C = CoordinateType,
0337         std::enable_if_t<geometry::detail::is_coordinates_number_eq<C, 3, DimensionCount>::value, int> = 0
0338     >
0339     static constexpr point_type apply(CoordinateType const& v0,
0340                                       CoordinateType const& v1,
0341                                       CoordinateType const& v2)
0342     {
0343         return point_type(v0, v1, v2);
0344     }
0345 };
0346 
0347 
0348 } // namespace traits
0349 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
0350 
0351 #if defined(_MSC_VER)
0352 #pragma warning(pop)
0353 #endif
0354 
0355 }} // namespace boost::geometry
0356 
0357 #endif // BOOST_GEOMETRY_GEOMETRIES_POINT_HPP