File indexing completed on 2025-12-15 09:50:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP
0021 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP
0022
0023
0024 #include <deque>
0025
0026 #include <boost/geometry/core/reverse_dispatch.hpp>
0027 #include <boost/geometry/core/tag.hpp>
0028 #include <boost/geometry/core/tag_cast.hpp>
0029 #include <boost/geometry/core/tags.hpp>
0030 #include <boost/geometry/core/visit.hpp>
0031
0032 #include <boost/geometry/geometries/adapted/boost_variant.hpp>
0033 #include <boost/geometry/geometries/concepts/check.hpp>
0034
0035 #include <boost/geometry/strategies/default_strategy.hpp>
0036 #include <boost/geometry/strategies/detail.hpp>
0037 #include <boost/geometry/strategies/relate/services.hpp>
0038
0039
0040 namespace boost { namespace geometry
0041 {
0042
0043 #ifndef DOXYGEN_NO_DISPATCH
0044 namespace dispatch {
0045
0046
0047
0048 template
0049 <
0050 typename Geometry1,
0051 typename Geometry2,
0052 typename Tag1 = tag_t<Geometry1>,
0053 typename Tag2 = tag_t<Geometry2>,
0054 typename CastedTag1 = tag_cast_t<Tag1, pointlike_tag, linear_tag, areal_tag>,
0055 typename CastedTag2 = tag_cast_t<Tag2, pointlike_tag, linear_tag, areal_tag>,
0056 bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
0057 >
0058 struct touches
0059 : not_implemented<Tag1, Tag2>
0060 {};
0061
0062
0063 template
0064 <
0065 typename Geometry1, typename Geometry2,
0066 typename Tag1, typename Tag2,
0067 typename CastedTag1, typename CastedTag2
0068 >
0069 struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true>
0070 : touches<Geometry2, Geometry1, Tag2, Tag1, CastedTag2, CastedTag1, false>
0071 {
0072 template <typename Strategy>
0073 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
0074 {
0075 return touches<Geometry2, Geometry1>::apply(g2, g1, strategy);
0076 }
0077 };
0078
0079 }
0080 #endif
0081
0082
0083 namespace resolve_strategy
0084 {
0085
0086 template
0087 <
0088 typename Strategy,
0089 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0090 >
0091 struct touches
0092 {
0093 template <typename Geometry1, typename Geometry2>
0094 static inline bool apply(Geometry1 const& geometry1,
0095 Geometry2 const& geometry2,
0096 Strategy const& strategy)
0097 {
0098 return dispatch::touches
0099 <
0100 Geometry1, Geometry2
0101 >::apply(geometry1, geometry2, strategy);
0102 }
0103 };
0104
0105 template <typename Strategy>
0106 struct touches<Strategy, false>
0107 {
0108 template <typename Geometry1, typename Geometry2>
0109 static inline bool apply(Geometry1 const& geometry1,
0110 Geometry2 const& geometry2,
0111 Strategy const& strategy)
0112 {
0113 using strategies::relate::services::strategy_converter;
0114
0115 return dispatch::touches
0116 <
0117 Geometry1, Geometry2
0118 >::apply(geometry1, geometry2,
0119 strategy_converter<Strategy>::get(strategy));
0120 }
0121 };
0122
0123 template <>
0124 struct touches<default_strategy, false>
0125 {
0126 template <typename Geometry1, typename Geometry2>
0127 static inline bool apply(Geometry1 const& geometry1,
0128 Geometry2 const& geometry2,
0129 default_strategy)
0130 {
0131 typedef typename strategies::relate::services::default_strategy
0132 <
0133 Geometry1,
0134 Geometry2
0135 >::type strategy_type;
0136
0137 return dispatch::touches
0138 <
0139 Geometry1, Geometry2
0140 >::apply(geometry1, geometry2, strategy_type());
0141 }
0142 };
0143
0144 }
0145
0146
0147 namespace resolve_dynamic {
0148
0149 template
0150 <
0151 typename Geometry1, typename Geometry2,
0152 typename Tag1 = geometry::tag_t<Geometry1>,
0153 typename Tag2 = geometry::tag_t<Geometry2>
0154 >
0155 struct touches
0156 {
0157 template <typename Strategy>
0158 static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0159 Strategy const& strategy)
0160 {
0161 concepts::check<Geometry1 const>();
0162 concepts::check<Geometry2 const>();
0163
0164 return resolve_strategy::touches
0165 <
0166 Strategy
0167 >::apply(geometry1, geometry2, strategy);
0168 }
0169 };
0170
0171 template <typename Geometry1, typename Geometry2, typename Tag2>
0172 struct touches<Geometry1, Geometry2, dynamic_geometry_tag, Tag2>
0173 {
0174 template <typename Strategy>
0175 static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0176 Strategy const& strategy)
0177 {
0178 bool result = false;
0179 traits::visit<Geometry1>::apply([&](auto const& g1)
0180 {
0181 result = touches
0182 <
0183 util::remove_cref_t<decltype(g1)>,
0184 Geometry2
0185 >::apply(g1, geometry2, strategy);
0186 }, geometry1);
0187 return result;
0188 }
0189 };
0190
0191 template <typename Geometry1, typename Geometry2, typename Tag1>
0192 struct touches<Geometry1, Geometry2, Tag1, dynamic_geometry_tag>
0193 {
0194 template <typename Strategy>
0195 static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0196 Strategy const& strategy)
0197 {
0198 bool result = false;
0199 traits::visit<Geometry2>::apply([&](auto const& g2)
0200 {
0201 result = touches
0202 <
0203 Geometry1,
0204 util::remove_cref_t<decltype(g2)>
0205 >::apply(geometry1, g2, strategy);
0206 }, geometry2);
0207 return result;
0208 }
0209 };
0210
0211 template <typename Geometry1, typename Geometry2>
0212 struct touches<Geometry1, Geometry2, dynamic_geometry_tag, dynamic_geometry_tag>
0213 {
0214 template <typename Strategy>
0215 static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0216 Strategy const& strategy)
0217 {
0218 bool result = false;
0219 traits::visit<Geometry1, Geometry2>::apply([&](auto const& g1, auto const& g2)
0220 {
0221 result = touches
0222 <
0223 util::remove_cref_t<decltype(g1)>,
0224 util::remove_cref_t<decltype(g2)>
0225 >::apply(g1, g2, strategy);
0226 }, geometry1, geometry2);
0227 return result;
0228 }
0229 };
0230
0231 template <typename Geometry, typename Tag = geometry::tag_t<Geometry>>
0232 struct self_touches;
0233
0234 template <typename Geometry>
0235 struct self_touches<Geometry, dynamic_geometry_tag>
0236 {
0237 static bool apply(Geometry const& geometry)
0238 {
0239 bool result = false;
0240 traits::visit<Geometry>::apply([&](auto const& g)
0241 {
0242 result = self_touches
0243 <
0244 util::remove_cref_t<decltype(g)>
0245 >::apply(g);
0246 }, geometry);
0247 return result;
0248 }
0249 };
0250
0251 }
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272 template <typename Geometry>
0273 inline bool touches(Geometry const& geometry)
0274 {
0275 return resolve_dynamic::self_touches<Geometry>::apply(geometry);
0276 }
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296 template <typename Geometry1, typename Geometry2>
0297 inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2)
0298 {
0299 return resolve_dynamic::touches
0300 <
0301 Geometry1, Geometry2
0302 >::apply(geometry1, geometry2, default_strategy());
0303 }
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 template <typename Geometry1, typename Geometry2, typename Strategy>
0320 inline bool touches(Geometry1 const& geometry1,
0321 Geometry2 const& geometry2,
0322 Strategy const& strategy)
0323 {
0324 return resolve_dynamic::touches
0325 <
0326 Geometry1, Geometry2
0327 >::apply(geometry1, geometry2, strategy);
0328 }
0329
0330
0331 }}
0332
0333 #endif