// Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2024 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2020. // Modifications copyright (c) 2020, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_GEOMETRY_CORE_ACCESS_HPP #define BOOST_GEOMETRY_CORE_ACCESS_HPP #include #include #include #include #include #include namespace boost { namespace geometry { /// Index of minimum corner of the box. BOOST_INLINE_CONSTEXPR int min_corner = 0; /// Index of maximum corner of the box. BOOST_INLINE_CONSTEXPR int max_corner = 1; namespace traits { /*! \brief Traits class which gives access (get,set) to points. \ingroup traits \par Geometries: /// @li point \par Specializations should provide, per Dimension /// @li static inline T get(G const&) /// @li static inline void set(G&, T const&) \tparam Geometry geometry-type \tparam Dimension dimension to access */ template struct access { BOOST_GEOMETRY_STATIC_ASSERT_FALSE( "Not implemented for this Geometry type.", Geometry); }; /*! \brief Traits class defining "get" and "set" to get and set point coordinate values \tparam Geometry geometry (box, segment) \tparam Index index (min_corner/max_corner for box, 0/1 for segment) \tparam Dimension dimension \par Geometries: - box - segment \par Specializations should provide: - static inline T get(G const&) - static inline void set(G&, T const&) \ingroup traits */ template struct indexed_access { BOOST_GEOMETRY_STATIC_ASSERT_FALSE( "Not implemented for this Geometry type.", Geometry); }; } // namespace traits #ifndef DOXYGEN_NO_DETAIL namespace detail { template < typename Geometry, std::size_t Index, std::size_t Dimension > struct indexed_access_non_pointer { static constexpr coordinate_type_t get(Geometry const& geometry) { return traits::indexed_access::get(geometry); } static void set(Geometry& b, coordinate_type_t const& value) { traits::indexed_access::set(b, value); } }; template < typename Geometry, std::size_t Index, std::size_t Dimension > struct indexed_access_pointer { static constexpr coordinate_type_t get(Geometry const* geometry) { return traits::indexed_access, Index, Dimension>::get(*geometry); } static void set(Geometry* geometry, coordinate_type_t const& value) { traits::indexed_access, Index, Dimension>::set(*geometry, value); } }; } // namespace detail #endif // DOXYGEN_NO_DETAIL #ifndef DOXYGEN_NO_DISPATCH namespace core_dispatch { template < typename Tag, typename Geometry, std::size_t Dimension, bool IsPointer > struct access { BOOST_GEOMETRY_STATIC_ASSERT_FALSE( "Not implemented for this Geometry Tag type.", Geometry, Tag); //static inline T get(G const&) {} //static inline void set(G& g, T const& value) {} }; template < typename Tag, typename Geometry, std::size_t Index, std::size_t Dimension, bool IsPointer > struct indexed_access { BOOST_GEOMETRY_STATIC_ASSERT_FALSE( "Not implemented for this Geometry Tag type.", Geometry, Tag); //static inline T get(G const&) {} //static inline void set(G& g, T const& value) {} }; template struct access { static constexpr coordinate_type_t get(Point const& point) { return traits::access::get(point); } static void set(Point& p, coordinate_type_t const& value) { traits::access::set(p, value); } }; template struct access { static constexpr coordinate_type_t get(Point const* point) { return traits::access, Dimension>::get(*point); } static void set(Point* p, coordinate_type_t const& value) { traits::access, Dimension>::set(*p, value); } }; template < typename Box, std::size_t Index, std::size_t Dimension > struct indexed_access : detail::indexed_access_non_pointer {}; template < typename Box, std::size_t Index, std::size_t Dimension > struct indexed_access : detail::indexed_access_pointer {}; template < typename Segment, std::size_t Index, std::size_t Dimension > struct indexed_access : detail::indexed_access_non_pointer {}; template < typename Segment, std::size_t Index, std::size_t Dimension > struct indexed_access : detail::indexed_access_pointer {}; } // namespace core_dispatch #endif // DOXYGEN_NO_DISPATCH #ifndef DOXYGEN_NO_DETAIL namespace detail { // Two dummy tags to distinguish get/set variants below. // They don't have to be specified by the user. The functions are distinguished // by template signature also, but for e.g. GCC this is not enough. So give them // a different signature. struct signature_getset_dimension {}; struct signature_getset_index_dimension {}; } // namespace detail #endif // DOXYGEN_NO_DETAIL /*! \brief Get coordinate value of a geometry (usually a point) \details \details_get_set \ingroup get \tparam Dimension \tparam_dimension_required \tparam Geometry \tparam_geometry (usually a Point Concept) \param geometry \param_geometry (usually a point) \return The coordinate value of specified dimension of specified geometry \qbk{[include reference/core/get_point.qbk]} */ template constexpr inline coordinate_type_t get(Geometry const& geometry #ifndef DOXYGEN_SHOULD_SKIP_THIS , detail::signature_getset_dimension* = 0 #endif ) { return core_dispatch::access < tag_t, util::remove_cptrref_t, Dimension, std::is_pointer::value >::get(geometry); } /*! \brief Set coordinate value of a geometry (usually a point) \details \details_get_set \tparam Dimension \tparam_dimension_required \tparam Geometry \tparam_geometry (usually a Point Concept) \param geometry \param_geometry \param value The coordinate value to set \ingroup set \qbk{[include reference/core/set_point.qbk]} */ template inline void set(Geometry& geometry , coordinate_type_t const& value #ifndef DOXYGEN_SHOULD_SKIP_THIS , detail::signature_getset_dimension* = 0 #endif ) { core_dispatch::access < tag_t, util::remove_cptrref_t, Dimension, std::is_pointer::value >::set(geometry, value); } /*! \brief get coordinate value of a Box or Segment \details \details_get_set \tparam Index \tparam_index_required \tparam Dimension \tparam_dimension_required \tparam Geometry \tparam_box_or_segment \param geometry \param_geometry \return coordinate value \ingroup get \qbk{distinguish,with index} \qbk{[include reference/core/get_box.qbk]} */ template constexpr inline coordinate_type_t get(Geometry const& geometry #ifndef DOXYGEN_SHOULD_SKIP_THIS , detail::signature_getset_index_dimension* = 0 #endif ) { return core_dispatch::indexed_access < tag_t, util::remove_cptrref_t, Index, Dimension, std::is_pointer::value >::get(geometry); } /*! \brief set coordinate value of a Box / Segment \details \details_get_set \tparam Index \tparam_index_required \tparam Dimension \tparam_dimension_required \tparam Geometry \tparam_box_or_segment \param geometry \param_geometry \param value The coordinate value to set \ingroup set \qbk{distinguish,with index} \qbk{[include reference/core/set_box.qbk]} */ template inline void set(Geometry& geometry , coordinate_type_t const& value #ifndef DOXYGEN_SHOULD_SKIP_THIS , detail::signature_getset_index_dimension* = 0 #endif ) { core_dispatch::indexed_access < tag_t, util::remove_cptrref_t, Index, Dimension, std::is_pointer::value >::set(geometry, value); } }} // namespace boost::geometry #endif // BOOST_GEOMETRY_CORE_ACCESS_HPP