Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // This file was modified by Oracle on 2013-2022.
0006 // Modifications copyright (c) 2013-2022 Oracle and/or its affiliates.
0007 
0008 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0009 
0010 // Use, modification and distribution is subject to the Boost Software License,
0011 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0012 // http://www.boost.org/LICENSE_1_0.txt)
0013 
0014 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
0015 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP
0016 
0017 
0018 #include <tuple>
0019 
0020 #include <boost/geometry/algorithms/detail/relate/de9im.hpp>
0021 #include <boost/geometry/algorithms/not_implemented.hpp>
0022 #include <boost/geometry/core/coordinate_dimension.hpp>
0023 #include <boost/geometry/core/tag.hpp>
0024 #include <boost/geometry/core/tags.hpp>
0025 #include <boost/geometry/core/topological_dimension.hpp>
0026 #include <boost/geometry/geometries/adapted/boost_variant.hpp>
0027 #include <boost/geometry/geometries/concepts/check.hpp>
0028 #include <boost/geometry/strategies/default_strategy.hpp>
0029 #include <boost/geometry/strategies/detail.hpp>
0030 #include <boost/geometry/strategies/relate/services.hpp>
0031 #include <boost/geometry/util/sequence.hpp>
0032 #include <boost/geometry/util/type_traits.hpp>
0033 
0034 
0035 namespace boost { namespace geometry {
0036 
0037 
0038 #ifndef DOXYGEN_NO_DETAIL
0039 namespace detail { namespace relate {
0040 
0041 // is_generic allows dispatch::relate to generate compile-time error
0042 template <typename Geometry1, typename Geometry2>
0043 struct is_generic
0044 {
0045     static const bool value = (util::is_polysegmental<Geometry1>::value
0046                             && util::is_polysegmental<Geometry2>::value)
0047                               ||
0048                               (util::is_point<Geometry1>::value
0049                             && util::is_polysegmental<Geometry2>::value)
0050                               ||
0051                               (util::is_polysegmental<Geometry1>::value
0052                             && util::is_point<Geometry2>::value);
0053 };
0054 
0055 }} // namespace detail::relate
0056 #endif // DOXYGEN_NO_DETAIL
0057 
0058 
0059 #ifndef DOXYGEN_NO_DISPATCH
0060 namespace dispatch {
0061 
0062 
0063 template <typename Geometry1,
0064           typename Geometry2,
0065           typename Tag1 = typename geometry::tag<Geometry1>::type,
0066           typename Tag2 = typename geometry::tag<Geometry2>::type,
0067           int TopDim1 = geometry::topological_dimension<Geometry1>::value,
0068           int TopDim2 = geometry::topological_dimension<Geometry2>::value,
0069           bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
0070 >
0071 struct relate : not_implemented<Tag1, Tag2>
0072 {};
0073 
0074 } // namespace dispatch
0075 #endif // DOXYGEN_NO_DISPATCH
0076 
0077 #ifndef DOXYGEN_NO_DETAIL
0078 namespace detail { namespace relate {
0079 
0080 template <typename Geometry1, typename Geometry2>
0081 struct interruption_enabled
0082 {
0083     static const bool value =
0084         dispatch::relate<Geometry1, Geometry2>::interruption_enabled;
0085 };
0086 
0087 template <typename Geometry1, typename Geometry2, typename Result>
0088 struct result_handler_type
0089     : not_implemented<Result>
0090 {};
0091 
0092 template <typename Geometry1, typename Geometry2>
0093 struct result_handler_type<Geometry1, Geometry2, geometry::de9im::mask>
0094 {
0095     typedef mask_handler
0096         <
0097             geometry::de9im::mask,
0098             interruption_enabled
0099                 <
0100                     Geometry1,
0101                     Geometry2
0102                 >::value
0103         > type;
0104 };
0105 
0106 template <typename Geometry1, typename Geometry2, typename ...Masks>
0107 struct result_handler_type<Geometry1, Geometry2, std::tuple<Masks...>>
0108 {
0109     typedef mask_handler
0110         <
0111             std::tuple<Masks...>,
0112             interruption_enabled
0113                 <
0114                     Geometry1,
0115                     Geometry2
0116                 >::value
0117         > type;
0118 };
0119 
0120 template <typename Geometry1, typename Geometry2,
0121           char II, char IB, char IE,
0122           char BI, char BB, char BE,
0123           char EI, char EB, char EE>
0124 struct result_handler_type
0125     <
0126         Geometry1,
0127         Geometry2,
0128         geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
0129     >
0130 {
0131     typedef static_mask_handler
0132         <
0133             geometry::de9im::static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
0134             interruption_enabled
0135                 <
0136                     Geometry1,
0137                     Geometry2
0138                 >::value
0139         > type;
0140 };
0141 
0142 template <typename Geometry1, typename Geometry2, typename ...StaticMasks>
0143 struct result_handler_type<Geometry1, Geometry2, util::type_sequence<StaticMasks...>>
0144 {
0145     typedef static_mask_handler
0146         <
0147             util::type_sequence<StaticMasks...>,
0148             interruption_enabled
0149                 <
0150                     Geometry1,
0151                     Geometry2
0152                 >::value
0153         > type;
0154 };
0155 
0156 
0157 }} // namespace detail::relate
0158 #endif // DOXYGEN_NO_DETAIL
0159 
0160 namespace resolve_strategy
0161 {
0162 
0163 template
0164 <
0165     typename Strategy,
0166     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0167 >
0168 struct relate
0169 {
0170     template <typename Geometry1, typename Geometry2, typename ResultHandler>
0171     static inline void apply(Geometry1 const& geometry1,
0172                              Geometry2 const& geometry2,
0173                              ResultHandler & handler,
0174                              Strategy const& strategy)
0175     {
0176         dispatch::relate
0177             <
0178                 Geometry1,
0179                 Geometry2
0180             >::apply(geometry1, geometry2, handler, strategy);
0181     }
0182 };
0183 
0184 template <typename Strategy>
0185 struct relate<Strategy, false>
0186 {
0187     template <typename Geometry1, typename Geometry2, typename ResultHandler>
0188     static inline void apply(Geometry1 const& geometry1,
0189                              Geometry2 const& geometry2,
0190                              ResultHandler & handler,
0191                              Strategy const& strategy)
0192     {
0193         using strategies::relate::services::strategy_converter;
0194         dispatch::relate
0195             <
0196                 Geometry1,
0197                 Geometry2
0198             >::apply(geometry1, geometry2, handler,
0199                      strategy_converter<Strategy>::get(strategy));
0200     }
0201 };
0202 
0203 template <>
0204 struct relate<default_strategy, false>
0205 {
0206     template <typename Geometry1, typename Geometry2, typename ResultHandler>
0207     static inline void apply(Geometry1 const& geometry1,
0208                              Geometry2 const& geometry2,
0209                              ResultHandler & handler,
0210                              default_strategy)
0211     {
0212         typedef typename strategies::relate::services::default_strategy
0213             <
0214                 Geometry1,
0215                 Geometry2
0216             >::type strategy_type;
0217 
0218         dispatch::relate
0219             <
0220                 Geometry1,
0221                 Geometry2
0222             >::apply(geometry1, geometry2, handler, strategy_type());
0223     }
0224 };
0225 
0226 } // resolve_strategy
0227 
0228 namespace resolve_dynamic
0229 {
0230 
0231 template
0232 <
0233     typename Geometry1, typename Geometry2,
0234     typename Tag1 = typename geometry::tag<Geometry1>::type,
0235     typename Tag2 = typename geometry::tag<Geometry2>::type
0236 >
0237 struct relate
0238 {
0239     template <typename Mask, typename Strategy>
0240     static inline bool apply(Geometry1 const& geometry1,
0241                              Geometry2 const& geometry2,
0242                              Mask const& mask,
0243                              Strategy const& strategy)
0244     {
0245         concepts::check<Geometry1 const>();
0246         concepts::check<Geometry2 const>();
0247         assert_dimension_equal<Geometry1, Geometry2>();
0248 
0249         typename detail::relate::result_handler_type
0250             <
0251                 Geometry1,
0252                 Geometry2,
0253                 Mask
0254             >::type handler(mask);
0255 
0256         resolve_strategy::relate<Strategy>::apply(geometry1, geometry2, handler, strategy);
0257 
0258         return handler.result();
0259     }
0260 };
0261 
0262 template <typename Geometry1, typename Geometry2, typename Tag2>
0263 struct relate<Geometry1, Geometry2, dynamic_geometry_tag, Tag2>
0264 {
0265     template <typename Mask, typename Strategy>
0266     static inline bool apply(Geometry1 const& geometry1,
0267                              Geometry2 const& geometry2,
0268                              Mask const& mask,
0269                              Strategy const& strategy)
0270     {
0271         bool result = false;
0272         traits::visit<Geometry1>::apply([&](auto const& g1)
0273         {
0274             result = relate
0275                 <
0276                     util::remove_cref_t<decltype(g1)>,
0277                     Geometry2
0278                 >::apply(g1, geometry2, mask, strategy);
0279         }, geometry1);
0280         return result;
0281     }
0282 };
0283 
0284 template <typename Geometry1, typename Geometry2, typename Tag1>
0285 struct relate<Geometry1, Geometry2, Tag1, dynamic_geometry_tag>
0286 {
0287     template <typename Mask, typename Strategy>
0288     static inline bool apply(Geometry1 const& geometry1,
0289                              Geometry2 const& geometry2,
0290                              Mask const& mask,
0291                              Strategy const& strategy)
0292     {
0293         bool result = false;
0294         traits::visit<Geometry2>::apply([&](auto const& g2)
0295         {
0296             result = relate
0297                 <
0298                     Geometry1,
0299                     util::remove_cref_t<decltype(g2)>
0300                 >::apply(geometry1, g2, mask, strategy);
0301         }, geometry2);
0302         return result;
0303     }
0304 };
0305 
0306 template <typename Geometry1, typename Geometry2>
0307 struct relate<Geometry1, Geometry2, dynamic_geometry_tag, dynamic_geometry_tag>
0308 {
0309     template <typename Mask, typename Strategy>
0310     static inline bool apply(Geometry1 const& geometry1,
0311                              Geometry2 const& geometry2,
0312                              Mask const& mask,
0313                              Strategy const& strategy)
0314     {
0315         bool result = false;
0316         traits::visit<Geometry1, Geometry2>::apply([&](auto const& g1, auto const& g2)
0317         {
0318             result = relate
0319                 <
0320                     util::remove_cref_t<decltype(g1)>,
0321                     util::remove_cref_t<decltype(g2)>
0322                 >::apply(g1, g2, mask, strategy);
0323         }, geometry1, geometry2);
0324         return result;
0325     }
0326 };
0327 
0328 } // namespace resolve_dynamic
0329 
0330 /*!
0331 \brief Checks relation between a pair of geometries defined by a mask.
0332 \ingroup relate
0333 \tparam Geometry1 \tparam_geometry
0334 \tparam Geometry2 \tparam_geometry
0335 \tparam Mask An intersection model Mask type.
0336 \tparam Strategy \tparam_strategy{Relate}
0337 \param geometry1 \param_geometry
0338 \param geometry2 \param_geometry
0339 \param mask An intersection model mask object.
0340 \param strategy \param_strategy{relate}
0341 \return true if the relation is compatible with the mask, false otherwise.
0342 
0343 \qbk{distinguish,with strategy}
0344 \qbk{[include reference/algorithms/relate.qbk]}
0345  */
0346 template <typename Geometry1, typename Geometry2, typename Mask, typename Strategy>
0347 inline bool relate(Geometry1 const& geometry1,
0348                    Geometry2 const& geometry2,
0349                    Mask const& mask,
0350                    Strategy const& strategy)
0351 {
0352     return resolve_dynamic::relate
0353             <
0354                 Geometry1,
0355                 Geometry2
0356             >::apply(geometry1, geometry2, mask, strategy);
0357 }
0358 
0359 /*!
0360 \brief Checks relation between a pair of geometries defined by a mask.
0361 \ingroup relate
0362 \tparam Geometry1 \tparam_geometry
0363 \tparam Geometry2 \tparam_geometry
0364 \tparam Mask An intersection model Mask type.
0365 \param geometry1 \param_geometry
0366 \param geometry2 \param_geometry
0367 \param mask An intersection model mask object.
0368 \return true if the relation is compatible with the mask, false otherwise.
0369 
0370 \qbk{[include reference/algorithms/relate.qbk]}
0371  */
0372 template <typename Geometry1, typename Geometry2, typename Mask>
0373 inline bool relate(Geometry1 const& geometry1,
0374                    Geometry2 const& geometry2,
0375                    Mask const& mask)
0376 {
0377     return resolve_dynamic::relate
0378             <
0379                 Geometry1,
0380                 Geometry2
0381             >::apply(geometry1, geometry2, mask, default_strategy());
0382 }
0383 
0384 }} // namespace boost::geometry
0385 
0386 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_INTERFACE_HPP