tuples.hpp 4.2 KB

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