1 // Boost.Geometry Index
2 //
3 // Copyright (c) 2011-2016 Adam Wulkiewicz, Lodz, Poland.
4 //
5 // Use, modification and distribution is subject to the Boost Software License,
6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 
9 #ifndef BOOST_GEOMETRY_INDEX_EQUAL_TO_HPP
10 #define BOOST_GEOMETRY_INDEX_EQUAL_TO_HPP
11 
12 #include <boost/geometry/algorithms/detail/equals/interface.hpp>
13 #include <boost/geometry/index/indexable.hpp>
14 
15 namespace boost { namespace geometry { namespace index { namespace detail {
16 
17 template <typename Geometry,
18           typename Tag = typename geometry::tag<Geometry>::type>
19 struct equals
20 {
applyboost::geometry::index::detail::equals21     inline static bool apply(Geometry const& g1, Geometry const& g2)
22     {
23         return geometry::equals(g1, g2);
24     }
25 };
26 
27 template <typename Geometry, typename Tag>
28 struct equals<Geometry *, Tag>
29 {
applyboost::geometry::index::detail::equals30     inline static bool apply(const Geometry * g1, const Geometry * g2)
31     {
32         return g1 == g2;
33     }
34 };
35 
36 template <typename T>
37 struct equals<T, void>
38 {
applyboost::geometry::index::detail::equals39     inline static bool apply(T const& v1, T const& v2)
40     {
41         return v1 == v2;
42     }
43 };
44 
45 template <typename T>
46 struct equals<T *, void>
47 {
applyboost::geometry::index::detail::equals48     inline static bool apply(const T * v1, const T * v2)
49     {
50         return v1 == v2;
51     }
52 };
53 
54 template <typename Tuple, size_t I, size_t N>
55 struct tuple_equals
56 {
applyboost::geometry::index::detail::tuple_equals57     inline static bool apply(Tuple const& t1, Tuple const& t2)
58     {
59         typedef typename boost::tuples::element<I, Tuple>::type T;
60 
61         return equals<T>::apply(boost::get<I>(t1), boost::get<I>(t2))
62             && tuple_equals<Tuple, I+1, N>::apply(t1, t2);
63     }
64 };
65 
66 template <typename Tuple, size_t I>
67 struct tuple_equals<Tuple, I, I>
68 {
applyboost::geometry::index::detail::tuple_equals69     inline static bool apply(Tuple const&, Tuple const&)
70     {
71         return true;
72     }
73 };
74 
75 // TODO: Consider this: Since equal_to<> is using geometry::equals() it's possible that
76 //       two compared Indexables are not exactly the same! They will be spatially equal
77 //       but not strictly equal. Consider 2 Segments with reversed order of points.
78 //       Therefore it's possible that during the Value removal different value will be
79 //       removed than the one that was passed.
80 
81 /*!
82 \brief The function object comparing Values.
83 
84 It compares Geometries using geometry::equals() function. Other types are compared using operator==.
85 The default version handles Values which are Indexables.
86 This template is also specialized for std::pair<T1, T2> and boost::tuple<...>.
87 
88 \tparam Value       The type of objects which are compared by this function object.
89 \tparam IsIndexable If true, Values are compared using boost::geometry::equals() functions.
90 */
91 template <typename Value,
92           bool IsIndexable = is_indexable<Value>::value>
93 struct equal_to
94 {
95     /*! \brief The type of result returned by function object. */
96     typedef bool result_type;
97 
98     /*!
99     \brief Compare values. If Value is a Geometry geometry::equals() function is used.
100 
101     \param l First value.
102     \param r Second value.
103     \return true if values are equal.
104     */
operator ()boost::geometry::index::detail::equal_to105     inline bool operator()(Value const& l, Value const& r) const
106     {
107         return detail::equals<Value>::apply(l ,r);
108     }
109 };
110 
111 /*!
112 \brief The function object comparing Values.
113 
114 This specialization compares values of type std::pair<T1, T2>.
115 It compares pairs' first values, then second values.
116 
117 \tparam T1       The first type.
118 \tparam T2       The second type.
119 */
120 template <typename T1, typename T2>
121 struct equal_to<std::pair<T1, T2>, false>
122 {
123     /*! \brief The type of result returned by function object. */
124     typedef bool result_type;
125 
126     /*!
127     \brief Compare values. If pair<> Value member is a Geometry geometry::equals() function is used.
128 
129     \param l First value.
130     \param r Second value.
131     \return true if values are equal.
132     */
operator ()boost::geometry::index::detail::equal_to133     inline bool operator()(std::pair<T1, T2> const& l, std::pair<T1, T2> const& r) const
134     {
135         return detail::equals<T1>::apply(l.first, r.first)
136             && detail::equals<T2>::apply(l.second, r.second);
137     }
138 };
139 
140 /*!
141 \brief The function object comparing Values.
142 
143 This specialization compares values of type boost::tuple<...>.
144 It compares all members of the tuple from the first one to the last one.
145 */
146 template <typename T0, typename T1, typename T2, typename T3, typename T4,
147           typename T5, typename T6, typename T7, typename T8, typename T9>
148 struct equal_to<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, false>
149 {
150     typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> value_type;
151 
152     /*! \brief The type of result returned by function object. */
153     typedef bool result_type;
154 
155     /*!
156     \brief Compare values. If tuple<> Value member is a Geometry geometry::equals() function is used.
157 
158     \param l First value.
159     \param r Second value.
160     \return true if values are equal.
161     */
operator ()boost::geometry::index::detail::equal_to162     inline bool operator()(value_type const& l, value_type const& r) const
163     {
164         return detail::tuple_equals<
165             value_type, 0, boost::tuples::length<value_type>::value
166         >::apply(l ,r);
167     }
168 };
169 
170 }}}} // namespace boost::geometry::index::detail
171 
172 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
173 
174 #include <tuple>
175 
176 namespace boost { namespace geometry { namespace index { namespace detail {
177 
178 template <typename Tuple, size_t I, size_t N>
179 struct std_tuple_equals
180 {
applyboost::geometry::index::detail::std_tuple_equals181     inline static bool apply(Tuple const& t1, Tuple const& t2)
182     {
183         typedef typename std::tuple_element<I, Tuple>::type T;
184 
185         return equals<T>::apply(std::get<I>(t1), std::get<I>(t2))
186             && std_tuple_equals<Tuple, I+1, N>::apply(t1, t2);
187     }
188 };
189 
190 template <typename Tuple, size_t I>
191 struct std_tuple_equals<Tuple, I, I>
192 {
applyboost::geometry::index::detail::std_tuple_equals193     inline static bool apply(Tuple const&, Tuple const&)
194     {
195         return true;
196     }
197 };
198 
199 /*!
200 \brief The function object comparing Values.
201 
202 This specialization compares values of type std::tuple<Args...>.
203 It's defined if the compiler supports tuples and variadic templates.
204 It compares all members of the tuple from the first one to the last one.
205 */
206 template <typename ...Args>
207 struct equal_to<std::tuple<Args...>, false>
208 {
209     typedef std::tuple<Args...> value_type;
210 
211     /*! \brief The type of result returned by function object. */
212     typedef bool result_type;
213 
214     /*!
215     \brief Compare values. If tuple<> Value member is a Geometry geometry::equals() function is used.
216 
217     \param l First value.
218     \param r Second value.
219     \return true if values are equal.
220     */
operator ()boost::geometry::index::detail::equal_to221     bool operator()(value_type const& l, value_type const& r) const
222     {
223         return detail::std_tuple_equals<
224             value_type, 0, std::tuple_size<value_type>::value
225         >::apply(l ,r);
226     }
227 };
228 
229 }}}} // namespace boost::geometry::index::detail
230 
231 #endif // !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
232 
233 namespace boost { namespace geometry { namespace index {
234 
235 /*!
236 \brief The function object comparing Values.
237 
238 The default version handles Values which are Indexables, std::pair<T1, T2>, boost::tuple<...>
239 and std::tuple<...> if STD tuples and variadic templates are supported.
240 All members are compared from left to right, Geometries using boost::geometry::equals() function,
241 other types using operator==.
242 
243 \tparam Value       The type of objects which are compared by this function object.
244 */
245 template <typename Value>
246 struct equal_to
247     : detail::equal_to<Value>
248 {
249     /*! \brief The type of result returned by function object. */
250     typedef typename detail::equal_to<Value>::result_type result_type;
251 
252     /*!
253     \brief Compare Values.
254 
255     \param l First value.
256     \param r Second value.
257     \return true if Values are equal.
258     */
operator ()boost::geometry::index::equal_to259     inline bool operator()(Value const& l, Value const& r) const
260     {
261         return detail::equal_to<Value>::operator()(l ,r);
262     }
263 };
264 
265 }}} // namespace boost::geometry::index
266 
267 #endif // BOOST_GEOMETRY_INDEX_EQUAL_TO_HPP
268