1 // Boost.Geometry Index 2 // 3 // Copyright (c) 2011-2013 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_DETAIL_TUPLES_HPP 10 #define BOOST_GEOMETRY_INDEX_DETAIL_TUPLES_HPP 11 12 #include <boost/tuple/tuple.hpp> 13 #include <boost/type_traits/is_same.hpp> 14 15 // TODO move this to index/tuples and separate algorithms 16 17 namespace boost { namespace geometry { namespace index { namespace detail { 18 19 namespace tuples { 20 21 // find_index 22 23 namespace detail { 24 25 template <typename Tuple, typename El, size_t N> 26 struct find_index; 27 28 template <typename Tuple, typename El, size_t N, typename CurrentEl> 29 struct find_index_impl 30 { 31 static const size_t value = find_index<Tuple, El, N - 1>::value; 32 }; 33 34 template <typename Tuple, typename El, size_t N> 35 struct find_index_impl<Tuple, El, N, El> 36 { 37 static const size_t value = N - 1; 38 }; 39 40 template <typename Tuple, typename El, typename CurrentEl> 41 struct find_index_impl<Tuple, El, 1, CurrentEl> 42 { 43 BOOST_MPL_ASSERT_MSG( 44 (false), 45 ELEMENT_NOT_FOUND, 46 (find_index_impl)); 47 }; 48 49 template <typename Tuple, typename El> 50 struct find_index_impl<Tuple, El, 1, El> 51 { 52 static const size_t value = 0; 53 }; 54 55 template <typename Tuple, typename El, size_t N> 56 struct find_index 57 { 58 static const size_t value = 59 find_index_impl< 60 Tuple, 61 El, 62 N, 63 typename boost::tuples::element<N - 1, Tuple>::type 64 >::value; 65 }; 66 67 } // namespace detail 68 69 template <typename Tuple, typename El> 70 struct find_index 71 { 72 static const size_t value = 73 detail::find_index< 74 Tuple, 75 El, 76 boost::tuples::length<Tuple>::value 77 >::value; 78 }; 79 80 // has 81 82 namespace detail { 83 84 template <typename Tuple, typename El, size_t N> 85 struct has 86 { 87 static const bool value 88 = boost::is_same< 89 typename boost::tuples::element<N - 1, Tuple>::type, 90 El 91 >::value 92 || has<Tuple, El, N - 1>::value; 93 }; 94 95 template <typename Tuple, typename El> 96 struct has<Tuple, El, 1> 97 { 98 static const bool value 99 = boost::is_same< 100 typename boost::tuples::element<0, Tuple>::type, 101 El 102 >::value; 103 }; 104 105 } // namespace detail 106 107 template <typename Tuple, typename El> 108 struct has 109 { 110 static const bool value 111 = detail::has< 112 Tuple, 113 El, 114 boost::tuples::length<Tuple>::value 115 >::value; 116 }; 117 118 // add 119 120 template <typename Tuple, typename El> 121 struct add 122 { 123 BOOST_MPL_ASSERT_MSG( 124 (false), 125 NOT_IMPLEMENTED_FOR_THIS_TUPLE_TYPE, 126 (add)); 127 }; 128 129 template <typename T1, typename T> 130 struct add<boost::tuple<T1>, T> 131 { 132 typedef boost::tuple<T1, T> type; 133 }; 134 135 template <typename T1, typename T2, typename T> 136 struct add<boost::tuple<T1, T2>, T> 137 { 138 typedef boost::tuple<T1, T2, T> type; 139 }; 140 141 // add_if 142 143 template <typename Tuple, typename El, bool Cond> 144 struct add_if 145 { 146 typedef Tuple type; 147 }; 148 149 template <typename Tuple, typename El> 150 struct add_if<Tuple, El, true> 151 { 152 typedef typename add<Tuple, El>::type type; 153 }; 154 155 // add_unique 156 157 template <typename Tuple, typename El> 158 struct add_unique 159 { 160 typedef typename add_if< 161 Tuple, 162 El, 163 !has<Tuple, El>::value 164 >::type type; 165 }; 166 167 template <typename Tuple, 168 typename T, 169 size_t I = 0, 170 size_t N = boost::tuples::length<Tuple>::value> 171 struct push_back 172 { 173 typedef 174 boost::tuples::cons< 175 typename boost::tuples::element<I, Tuple>::type, 176 typename push_back<Tuple, T, I+1, N>::type 177 > type; 178 applyboost::geometry::index::detail::tuples::push_back179 static type apply(Tuple const& tup, T const& t) 180 { 181 return 182 type( 183 boost::get<I>(tup), 184 push_back<Tuple, T, I+1, N>::apply(tup, t) 185 ); 186 } 187 }; 188 189 template <typename Tuple, typename T, size_t N> 190 struct push_back<Tuple, T, N, N> 191 { 192 typedef boost::tuples::cons<T, boost::tuples::null_type> type; 193 applyboost::geometry::index::detail::tuples::push_back194 static type apply(Tuple const&, T const& t) 195 { 196 return type(t, boost::tuples::null_type()); 197 } 198 }; 199 200 } // namespace tuples 201 202 }}}} // namespace boost::geometry::index::detail 203 204 #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_TAGS_HPP 205