1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
6 // Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
8 // This file was modified by Oracle on 2014, 2015, 2016, 2017.
9 // Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
17 // Use, modification and distribution is subject to the Boost Software License,
18 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
19 // http://www.boost.org/LICENSE_1_0.txt)
21 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_INTERFACE_HPP
22 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_INTERFACE_HPP
27 #include <boost/variant/apply_visitor.hpp>
28 #include <boost/variant/static_visitor.hpp>
29 #include <boost/variant/variant_fwd.hpp>
31 #include <boost/geometry/core/coordinate_dimension.hpp>
32 #include <boost/geometry/core/reverse_dispatch.hpp>
34 #include <boost/geometry/geometries/concepts/check.hpp>
36 #include <boost/geometry/algorithms/not_implemented.hpp>
38 #include <boost/geometry/strategies/default_strategy.hpp>
39 #include <boost/geometry/strategies/relate.hpp>
42 namespace boost { namespace geometry
45 #ifndef DOXYGEN_NO_DISPATCH
53 typename Tag1 = typename tag<Geometry1>::type,
54 typename Tag2 = typename tag<Geometry2>::type,
55 std::size_t DimensionCount = dimension<Geometry1>::type::value,
56 bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
58 struct equals: not_implemented<Tag1, Tag2>
62 // If reversal is needed, perform it
65 typename Geometry1, typename Geometry2,
66 typename Tag1, typename Tag2,
67 std::size_t DimensionCount
69 struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
70 : equals<Geometry2, Geometry1, Tag2, Tag1, DimensionCount, false>
72 template <typename Strategy>
73 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
81 >::apply(g2, g1, strategy);
86 } // namespace dispatch
87 #endif // DOXYGEN_NO_DISPATCH
90 namespace resolve_strategy
95 template <typename Geometry1, typename Geometry2, typename Strategy>
96 static inline bool apply(Geometry1 const& geometry1,
97 Geometry2 const& geometry2,
98 Strategy const& strategy)
100 return dispatch::equals
103 >::apply(geometry1, geometry2, strategy);
106 template <typename Geometry1, typename Geometry2>
107 static inline bool apply(Geometry1 const& geometry1,
108 Geometry2 const& geometry2,
111 typedef typename strategy::relate::services::default_strategy
115 >::type strategy_type;
117 return dispatch::equals
120 >::apply(geometry1, geometry2, strategy_type());
124 } // namespace resolve_strategy
127 namespace resolve_variant {
129 template <typename Geometry1, typename Geometry2>
132 template <typename Strategy>
133 static inline bool apply(Geometry1 const& geometry1,
134 Geometry2 const& geometry2,
135 Strategy const& strategy)
137 concepts::check_concepts_and_equal_dimensions
143 return resolve_strategy::equals
144 ::apply(geometry1, geometry2, strategy);
148 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
149 struct equals<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
151 template <typename Strategy>
152 struct visitor: static_visitor<bool>
154 Geometry2 const& m_geometry2;
155 Strategy const& m_strategy;
157 visitor(Geometry2 const& geometry2, Strategy const& strategy)
158 : m_geometry2(geometry2)
159 , m_strategy(strategy)
162 template <typename Geometry1>
163 inline bool operator()(Geometry1 const& geometry1) const
165 return equals<Geometry1, Geometry2>
166 ::apply(geometry1, m_geometry2, m_strategy);
171 template <typename Strategy>
172 static inline bool apply(
173 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
174 Geometry2 const& geometry2,
175 Strategy const& strategy
178 return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
182 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
183 struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
185 template <typename Strategy>
186 struct visitor: static_visitor<bool>
188 Geometry1 const& m_geometry1;
189 Strategy const& m_strategy;
191 visitor(Geometry1 const& geometry1, Strategy const& strategy)
192 : m_geometry1(geometry1)
193 , m_strategy(strategy)
196 template <typename Geometry2>
197 inline bool operator()(Geometry2 const& geometry2) const
199 return equals<Geometry1, Geometry2>
200 ::apply(m_geometry1, geometry2, m_strategy);
205 template <typename Strategy>
206 static inline bool apply(
207 Geometry1 const& geometry1,
208 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
209 Strategy const& strategy
212 return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
217 BOOST_VARIANT_ENUM_PARAMS(typename T1),
218 BOOST_VARIANT_ENUM_PARAMS(typename T2)
221 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
222 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
225 template <typename Strategy>
226 struct visitor: static_visitor<bool>
228 Strategy const& m_strategy;
230 visitor(Strategy const& strategy)
231 : m_strategy(strategy)
234 template <typename Geometry1, typename Geometry2>
235 inline bool operator()(Geometry1 const& geometry1,
236 Geometry2 const& geometry2) const
238 return equals<Geometry1, Geometry2>
239 ::apply(geometry1, geometry2, m_strategy);
244 template <typename Strategy>
245 static inline bool apply(
246 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
247 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
248 Strategy const& strategy
251 return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
255 } // namespace resolve_variant
259 \brief \brief_check{are spatially equal}
260 \details \details_check12{equals, is spatially equal}. Spatially equal means
261 that the same point set is included. A box can therefore be spatially equal
262 to a ring or a polygon, or a linestring can be spatially equal to a
263 multi-linestring or a segment. This only works theoretically, not all
264 combinations are implemented yet.
266 \tparam Geometry1 \tparam_geometry
267 \tparam Geometry2 \tparam_geometry
268 \tparam Strategy \tparam_strategy{Equals}
269 \param geometry1 \param_geometry
270 \param geometry2 \param_geometry
271 \param strategy \param_strategy{equals}
272 \return \return_check2{are spatially equal}
274 \qbk{distinguish,with strategy}
275 \qbk{[include reference/algorithms/equals.qbk]}
277 template <typename Geometry1, typename Geometry2, typename Strategy>
278 inline bool equals(Geometry1 const& geometry1,
279 Geometry2 const& geometry2,
280 Strategy const& strategy)
282 return resolve_variant::equals
285 >::apply(geometry1, geometry2, strategy);
290 \brief \brief_check{are spatially equal}
291 \details \details_check12{equals, is spatially equal}. Spatially equal means
292 that the same point set is included. A box can therefore be spatially equal
293 to a ring or a polygon, or a linestring can be spatially equal to a
294 multi-linestring or a segment. This only works theoretically, not all
295 combinations are implemented yet.
297 \tparam Geometry1 \tparam_geometry
298 \tparam Geometry2 \tparam_geometry
299 \param geometry1 \param_geometry
300 \param geometry2 \param_geometry
301 \return \return_check2{are spatially equal}
303 \qbk{[include reference/algorithms/equals.qbk]}
305 template <typename Geometry1, typename Geometry2>
306 inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
308 return resolve_variant::equals<Geometry1, Geometry2>
309 ::apply(geometry1, geometry2, default_strategy());
313 }} // namespace boost::geometry
316 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_INTERFACE_HPP