Boost.Geometry.Index
|
00001 // Boost.Geometry Index 00002 // 00003 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. 00004 // 00005 // Use, modification and distribution is subject to the Boost Software License, 00006 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 00007 // http://www.boost.org/LICENSE_1_0.txt) 00008 00009 #ifndef BOOST_GEOMETRY_INDEX_EQUAL_TO_HPP 00010 #define BOOST_GEOMETRY_INDEX_EQUAL_TO_HPP 00011 00012 #include <boost/geometry/algorithms/equals.hpp> 00013 #include <boost/geometry/index/indexable.hpp> 00014 00015 namespace boost { namespace geometry { namespace index { namespace detail { 00016 00017 template <typename Geometry, 00018 typename Tag = typename geometry::tag<Geometry>::type> 00019 struct equals 00020 { 00021 inline static bool apply(Geometry const& g1, Geometry const& g2) 00022 { 00023 return geometry::equals(g1, g2); 00024 } 00025 }; 00026 00027 template <typename Geometry, typename Tag> 00028 struct equals<Geometry *, Tag> 00029 { 00030 inline static bool apply(const Geometry * g1, const Geometry * g2) 00031 { 00032 return g1 == g2; 00033 } 00034 }; 00035 00036 template <typename T> 00037 struct equals<T, void> 00038 { 00039 inline static bool apply(T const& v1, T const& v2) 00040 { 00041 return v1 == v2; 00042 } 00043 }; 00044 00045 template <typename Tuple, size_t I, size_t N> 00046 struct tuple_equals 00047 { 00048 inline static bool apply(Tuple const& t1, Tuple const& t2) 00049 { 00050 typedef typename boost::tuples::element<I, Tuple>::type T; 00051 00052 return equals<T>::apply(boost::get<I>(t1), boost::get<I>(t2)) 00053 && tuple_equals<Tuple, I+1, N>::apply(t1, t2); 00054 } 00055 }; 00056 00057 template <typename Tuple, size_t I> 00058 struct tuple_equals<Tuple, I, I> 00059 { 00060 inline static bool apply(Tuple const&, Tuple const&) 00061 { 00062 return true; 00063 } 00064 }; 00065 00066 // TODO: Consider this: Since equal_to<> is using geometry::equals() it's possible that 00067 // two compared Indexables are not exactly the same! They will be spatially equal 00068 // but not strictly equal. Consider 2 Segments with reversed order of points. 00069 // Therefore it's possible that during the Value removal different value will be 00070 // removed than the one that was passed. 00071 00082 template <typename Value, 00083 bool IsIndexable = is_indexable<Value>::value> 00084 struct equal_to 00085 { 00087 typedef bool result_type; 00088 00096 inline bool operator()(Value const& l, Value const& r) const 00097 { 00098 return detail::equals<Value>::apply(l ,r); 00099 } 00100 }; 00101 00111 template <typename T1, typename T2> 00112 struct equal_to<std::pair<T1, T2>, false> 00113 { 00115 typedef bool result_type; 00116 00124 inline bool operator()(std::pair<T1, T2> const& l, std::pair<T1, T2> const& r) const 00125 { 00126 return detail::equals<T1>::apply(l.first, r.first) 00127 && detail::equals<T2>::apply(l.second, r.second); 00128 } 00129 }; 00130 00137 template <typename T0, typename T1, typename T2, typename T3, typename T4, 00138 typename T5, typename T6, typename T7, typename T8, typename T9> 00139 struct equal_to<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, false> 00140 { 00141 typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> value_type; 00142 00144 typedef bool result_type; 00145 00153 inline bool operator()(value_type const& l, value_type const& r) const 00154 { 00155 return detail::tuple_equals< 00156 value_type, 0, boost::tuples::length<value_type>::value 00157 >::apply(l ,r); 00158 } 00159 }; 00160 00161 }}}} // namespace boost::geometry::index::detail 00162 00163 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 00164 00165 #include <tuple> 00166 00167 namespace boost { namespace geometry { namespace index { namespace detail { 00168 00169 template <typename Tuple, size_t I, size_t N> 00170 struct std_tuple_equals 00171 { 00172 inline static bool apply(Tuple const& t1, Tuple const& t2) 00173 { 00174 typedef typename std::tuple_element<I, Tuple>::type T; 00175 00176 return equals<T>::apply(std::get<I>(t1), std::get<I>(t2)) 00177 && std_tuple_equals<Tuple, I+1, N>::apply(t1, t2); 00178 } 00179 }; 00180 00181 template <typename Tuple, size_t I> 00182 struct std_tuple_equals<Tuple, I, I> 00183 { 00184 inline static bool apply(Tuple const&, Tuple const&) 00185 { 00186 return true; 00187 } 00188 }; 00189 00197 template <typename ...Args> 00198 struct equal_to<std::tuple<Args...>, false> 00199 { 00200 typedef std::tuple<Args...> value_type; 00201 00203 typedef bool result_type; 00204 00212 bool operator()(value_type const& l, value_type const& r) const 00213 { 00214 return detail::std_tuple_equals< 00215 value_type, 0, std::tuple_size<value_type>::value 00216 >::apply(l ,r); 00217 } 00218 }; 00219 00220 }}}} // namespace boost::geometry::index::detail 00221 00222 #endif // !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 00223 00224 namespace boost { namespace geometry { namespace index { 00225 00236 template <typename Value> 00237 struct equal_to 00238 : detail::equal_to<Value> 00239 { 00241 typedef typename detail::equal_to<Value>::result_type result_type; 00242 00250 inline bool operator()(Value const& l, Value const& r) const 00251 { 00252 return detail::equal_to<Value>::operator()(l ,r); 00253 } 00254 }; 00255 00256 }}} // namespace boost::geometry::index 00257 00258 #endif // BOOST_GEOMETRY_INDEX_EQUAL_TO_HPP