1 | // Boost.Geometry Index |
2 | // |
3 | // Copyright (c) 2011-2014 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/equals.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 | { |
21 | 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 | { |
30 | 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 | { |
39 | inline static bool apply(T const& v1, T const& v2) |
40 | { |
41 | return v1 == v2; |
42 | } |
43 | }; |
44 | |
45 | template <typename Tuple, size_t I, size_t N> |
46 | struct tuple_equals |
47 | { |
48 | inline static bool apply(Tuple const& t1, Tuple const& t2) |
49 | { |
50 | typedef typename boost::tuples::element<I, Tuple>::type T; |
51 | |
52 | return equals<T>::apply(boost::get<I>(t1), boost::get<I>(t2)) |
53 | && tuple_equals<Tuple, I+1, N>::apply(t1, t2); |
54 | } |
55 | }; |
56 | |
57 | template <typename Tuple, size_t I> |
58 | struct tuple_equals<Tuple, I, I> |
59 | { |
60 | inline static bool apply(Tuple const&, Tuple const&) |
61 | { |
62 | return true; |
63 | } |
64 | }; |
65 | |
66 | // TODO: Consider this: Since equal_to<> is using geometry::equals() it's possible that |
67 | // two compared Indexables are not exactly the same! They will be spatially equal |
68 | // but not strictly equal. Consider 2 Segments with reversed order of points. |
69 | // Therefore it's possible that during the Value removal different value will be |
70 | // removed than the one that was passed. |
71 | |
72 | /*! |
73 | \brief The function object comparing Values. |
74 | |
75 | It compares Geometries using geometry::equals() function. Other types are compared using operator==. |
76 | The default version handles Values which are Indexables. |
77 | This template is also specialized for std::pair<T1, T2> and boost::tuple<...>. |
78 | |
79 | \tparam Value The type of objects which are compared by this function object. |
80 | \tparam IsIndexable If true, Values are compared using boost::geometry::equals() functions. |
81 | */ |
82 | template <typename Value, |
83 | bool IsIndexable = is_indexable<Value>::value> |
84 | struct equal_to |
85 | { |
86 | /*! \brief The type of result returned by function object. */ |
87 | typedef bool result_type; |
88 | |
89 | /*! |
90 | \brief Compare values. If Value is a Geometry geometry::equals() function is used. |
91 | |
92 | \param l First value. |
93 | \param r Second value. |
94 | \return true if values are equal. |
95 | */ |
96 | inline bool operator()(Value const& l, Value const& r) const |
97 | { |
98 | return detail::equals<Value>::apply(l ,r); |
99 | } |
100 | }; |
101 | |
102 | /*! |
103 | \brief The function object comparing Values. |
104 | |
105 | This specialization compares values of type std::pair<T1, T2>. |
106 | It compares pairs' first values, then second values. |
107 | |
108 | \tparam T1 The first type. |
109 | \tparam T2 The second type. |
110 | */ |
111 | template <typename T1, typename T2> |
112 | struct equal_to<std::pair<T1, T2>, false> |
113 | { |
114 | /*! \brief The type of result returned by function object. */ |
115 | typedef bool result_type; |
116 | |
117 | /*! |
118 | \brief Compare values. If pair<> Value member is a Geometry geometry::equals() function is used. |
119 | |
120 | \param l First value. |
121 | \param r Second value. |
122 | \return true if values are equal. |
123 | */ |
124 | inline bool operator()(std::pair<T1, T2> const& l, std::pair<T1, T2> const& r) const |
125 | { |
126 | return detail::equals<T1>::apply(l.first, r.first) |
127 | && detail::equals<T2>::apply(l.second, r.second); |
128 | } |
129 | }; |
130 | |
131 | /*! |
132 | \brief The function object comparing Values. |
133 | |
134 | This specialization compares values of type boost::tuple<...>. |
135 | It compares all members of the tuple from the first one to the last one. |
136 | */ |
137 | template <typename T0, typename T1, typename T2, typename T3, typename T4, |
138 | typename T5, typename T6, typename T7, typename T8, typename T9> |
139 | struct equal_to<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, false> |
140 | { |
141 | typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> value_type; |
142 | |
143 | /*! \brief The type of result returned by function object. */ |
144 | typedef bool result_type; |
145 | |
146 | /*! |
147 | \brief Compare values. If tuple<> Value member is a Geometry geometry::equals() function is used. |
148 | |
149 | \param l First value. |
150 | \param r Second value. |
151 | \return true if values are equal. |
152 | */ |
153 | inline bool operator()(value_type const& l, value_type const& r) const |
154 | { |
155 | return detail::tuple_equals< |
156 | value_type, 0, boost::tuples::length<value_type>::value |
157 | >::apply(l ,r); |
158 | } |
159 | }; |
160 | |
161 | }}}} // namespace boost::geometry::index::detail |
162 | |
163 | #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) |
164 | |
165 | #include <tuple> |
166 | |
167 | namespace boost { namespace geometry { namespace index { namespace detail { |
168 | |
169 | template <typename Tuple, size_t I, size_t N> |
170 | struct std_tuple_equals |
171 | { |
172 | inline static bool apply(Tuple const& t1, Tuple const& t2) |
173 | { |
174 | typedef typename std::tuple_element<I, Tuple>::type T; |
175 | |
176 | return equals<T>::apply(std::get<I>(t1), std::get<I>(t2)) |
177 | && std_tuple_equals<Tuple, I+1, N>::apply(t1, t2); |
178 | } |
179 | }; |
180 | |
181 | template <typename Tuple, size_t I> |
182 | struct std_tuple_equals<Tuple, I, I> |
183 | { |
184 | inline static bool apply(Tuple const&, Tuple const&) |
185 | { |
186 | return true; |
187 | } |
188 | }; |
189 | |
190 | /*! |
191 | \brief The function object comparing Values. |
192 | |
193 | This specialization compares values of type std::tuple<Args...>. |
194 | It's defined if the compiler supports tuples and variadic templates. |
195 | It compares all members of the tuple from the first one to the last one. |
196 | */ |
197 | template <typename ...Args> |
198 | struct equal_to<std::tuple<Args...>, false> |
199 | { |
200 | typedef std::tuple<Args...> value_type; |
201 | |
202 | /*! \brief The type of result returned by function object. */ |
203 | typedef bool result_type; |
204 | |
205 | /*! |
206 | \brief Compare values. If tuple<> Value member is a Geometry geometry::equals() function is used. |
207 | |
208 | \param l First value. |
209 | \param r Second value. |
210 | \return true if values are equal. |
211 | */ |
212 | bool operator()(value_type const& l, value_type const& r) const |
213 | { |
214 | return detail::std_tuple_equals< |
215 | value_type, 0, std::tuple_size<value_type>::value |
216 | >::apply(l ,r); |
217 | } |
218 | }; |
219 | |
220 | }}}} // namespace boost::geometry::index::detail |
221 | |
222 | #endif // !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) |
223 | |
224 | namespace boost { namespace geometry { namespace index { |
225 | |
226 | /*! |
227 | \brief The function object comparing Values. |
228 | |
229 | The default version handles Values which are Indexables, std::pair<T1, T2>, boost::tuple<...> |
230 | and std::tuple<...> if STD tuples and variadic templates are supported. |
231 | All members are compared from left to right, Geometries using boost::geometry::equals() function, |
232 | other types using operator==. |
233 | |
234 | \tparam Value The type of objects which are compared by this function object. |
235 | */ |
236 | template <typename Value> |
237 | struct equal_to |
238 | : detail::equal_to<Value> |
239 | { |
240 | /*! \brief The type of result returned by function object. */ |
241 | typedef typename detail::equal_to<Value>::result_type result_type; |
242 | |
243 | /*! |
244 | \brief Compare Values. |
245 | |
246 | \param l First value. |
247 | \param r Second value. |
248 | \return true if Values are equal. |
249 | */ |
250 | inline bool operator()(Value const& l, Value const& r) const |
251 | { |
252 | return detail::equal_to<Value>::operator()(l ,r); |
253 | } |
254 | }; |
255 | |
256 | }}} // namespace boost::geometry::index |
257 | |
258 | #endif // BOOST_GEOMETRY_INDEX_EQUAL_TO_HPP |
259 | |