tuples.hpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. // Boost.Geometry Index
  2. //
  3. // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
  4. //
  5. // This file was modified by Oracle on 2019-2020.
  6. // Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
  7. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  8. //
  9. // Use, modification and distribution is subject to the Boost Software License,
  10. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. #ifndef BOOST_GEOMETRY_UTIL_TUPLES_HPP
  13. #define BOOST_GEOMETRY_UTIL_TUPLES_HPP
  14. #include <tuple>
  15. #include <type_traits>
  16. #include <utility>
  17. #include <boost/geometry/core/config.hpp>
  18. #include <boost/tuple/tuple.hpp>
  19. namespace boost { namespace geometry { namespace tuples
  20. {
  21. template <typename T>
  22. struct is_tuple
  23. : std::integral_constant<bool, false>
  24. {};
  25. template <typename ...Ts>
  26. struct is_tuple<std::tuple<Ts...>>
  27. : std::integral_constant<bool, true>
  28. {};
  29. template <typename F, typename S>
  30. struct is_tuple<std::pair<F, S>>
  31. : std::integral_constant<bool, true>
  32. {};
  33. template <typename ...Ts>
  34. struct is_tuple<boost::tuples::tuple<Ts...>>
  35. : std::integral_constant<bool, true>
  36. {};
  37. template <typename HT, typename TT>
  38. struct is_tuple<boost::tuples::cons<HT, TT>>
  39. : std::integral_constant<bool, true>
  40. {};
  41. template <std::size_t I, typename Tuple>
  42. struct element;
  43. template <std::size_t I, typename ...Ts>
  44. struct element<I, std::tuple<Ts...>>
  45. : std::tuple_element<I, std::tuple<Ts...>>
  46. {};
  47. template <std::size_t I, typename HT, typename TT>
  48. struct element<I, std::pair<HT, TT>>
  49. : std::tuple_element<I, std::pair<HT, TT>>
  50. {};
  51. template <std::size_t I, typename ...Ts>
  52. struct element<I, boost::tuples::tuple<Ts...>>
  53. {
  54. typedef typename boost::tuples::element
  55. <
  56. I, boost::tuples::tuple<Ts...>
  57. >::type type;
  58. };
  59. template <std::size_t I, typename HT, typename TT>
  60. struct element<I, boost::tuples::cons<HT, TT>>
  61. {
  62. typedef typename boost::tuples::element
  63. <
  64. I, boost::tuples::cons<HT, TT>
  65. >::type type;
  66. };
  67. template <typename Tuple>
  68. struct size;
  69. template <typename ...Ts>
  70. struct size<std::tuple<Ts...>>
  71. : std::tuple_size<std::tuple<Ts...>>
  72. {};
  73. template <typename HT, typename TT>
  74. struct size<std::pair<HT, TT>>
  75. : std::tuple_size<std::pair<HT, TT>>
  76. {};
  77. template <typename ...Ts>
  78. struct size<boost::tuples::tuple<Ts...>>
  79. : std::integral_constant
  80. <
  81. std::size_t,
  82. boost::tuples::length<boost::tuples::tuple<Ts...>>::value
  83. >
  84. {};
  85. template <typename HT, typename TT>
  86. struct size<boost::tuples::cons<HT, TT>>
  87. : std::integral_constant
  88. <
  89. std::size_t,
  90. boost::tuples::length<boost::tuples::cons<HT, TT>>::value
  91. >
  92. {};
  93. template <std::size_t I, typename ...Ts>
  94. constexpr inline typename std::tuple_element<I, std::tuple<Ts...>>::type&
  95. get(std::tuple<Ts...> & t)
  96. {
  97. return std::get<I>(t);
  98. }
  99. template <std::size_t I, typename ...Ts>
  100. constexpr inline typename std::tuple_element<I, std::tuple<Ts...>>::type const&
  101. get(std::tuple<Ts...> const& t)
  102. {
  103. return std::get<I>(t);
  104. }
  105. template <std::size_t I, typename HT, typename TT>
  106. constexpr inline typename std::tuple_element<I, std::pair<HT, TT>>::type&
  107. get(std::pair<HT, TT> & t)
  108. {
  109. return std::get<I>(t);
  110. }
  111. template <std::size_t I, typename HT, typename TT>
  112. constexpr inline typename std::tuple_element<I, std::pair<HT, TT>>::type const&
  113. get(std::pair<HT, TT> const& t)
  114. {
  115. return std::get<I>(t);
  116. }
  117. template <std::size_t I, typename ...Ts>
  118. inline typename boost::tuples::access_traits
  119. <
  120. typename boost::tuples::element<I, boost::tuples::tuple<Ts...>>::type
  121. >::non_const_type
  122. get(boost::tuples::tuple<Ts...> & t)
  123. {
  124. return boost::tuples::get<I>(t);
  125. }
  126. template <std::size_t I, typename ...Ts>
  127. inline typename boost::tuples::access_traits
  128. <
  129. typename boost::tuples::element<I, boost::tuples::tuple<Ts...>>::type
  130. >::const_type
  131. get(boost::tuples::tuple<Ts...> const& t)
  132. {
  133. return boost::tuples::get<I>(t);
  134. }
  135. template <std::size_t I, typename HT, typename TT>
  136. inline typename boost::tuples::access_traits
  137. <
  138. typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
  139. >::non_const_type
  140. get(boost::tuples::cons<HT, TT> & tup)
  141. {
  142. return boost::tuples::get<I>(tup);
  143. }
  144. template <std::size_t I, typename HT, typename TT>
  145. inline typename boost::tuples::access_traits
  146. <
  147. typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
  148. >::const_type
  149. get(boost::tuples::cons<HT, TT> const& tup)
  150. {
  151. return boost::tuples::get<I>(tup);
  152. }
  153. // find_index_if
  154. // Searches for the index of an element for which UnaryPredicate returns true
  155. // If such element is not found the result is N
  156. template
  157. <
  158. typename Tuple,
  159. template <typename> class UnaryPred,
  160. std::size_t I = 0,
  161. std::size_t N = size<Tuple>::value
  162. >
  163. struct find_index_if
  164. : std::conditional_t
  165. <
  166. UnaryPred<typename element<I, Tuple>::type>::value,
  167. std::integral_constant<std::size_t, I>,
  168. typename find_index_if<Tuple, UnaryPred, I+1, N>::type
  169. >
  170. {};
  171. template
  172. <
  173. typename Tuple,
  174. template <typename> class UnaryPred,
  175. std::size_t N
  176. >
  177. struct find_index_if<Tuple, UnaryPred, N, N>
  178. : std::integral_constant<std::size_t, N>
  179. {};
  180. // find_if
  181. // Searches for an element for which UnaryPredicate returns true
  182. // If such element is not found the result is detail::null_type
  183. namespace detail
  184. {
  185. struct null_type {};
  186. } // detail
  187. template
  188. <
  189. typename Tuple,
  190. template <typename> class UnaryPred,
  191. std::size_t I = 0,
  192. std::size_t N = size<Tuple>::value
  193. >
  194. struct find_if
  195. : std::conditional_t
  196. <
  197. UnaryPred<typename element<I, Tuple>::type>::value,
  198. element<I, Tuple>,
  199. find_if<Tuple, UnaryPred, I+1, N>
  200. >
  201. {};
  202. template
  203. <
  204. typename Tuple,
  205. template <typename> class UnaryPred,
  206. std::size_t N
  207. >
  208. struct find_if<Tuple, UnaryPred, N, N>
  209. {
  210. typedef detail::null_type type;
  211. };
  212. // is_found
  213. // Returns true if a type T (the result of find_if) was found.
  214. template <typename T>
  215. struct is_found
  216. : std::integral_constant
  217. <
  218. bool,
  219. ! std::is_same<T, detail::null_type>::value
  220. >
  221. {};
  222. // is_not_found
  223. // Returns true if a type T (the result of find_if) was not found.
  224. template <typename T>
  225. struct is_not_found
  226. : std::is_same<T, detail::null_type>
  227. {};
  228. // exists_if
  229. // Returns true if search for element meeting UnaryPred can be found.
  230. template <typename Tuple, template <typename> class UnaryPred>
  231. struct exists_if
  232. : is_found<typename find_if<Tuple, UnaryPred>::type>
  233. {};
  234. // push_back
  235. // A utility used to create a type/object of a Tuple containing
  236. // all types/objects stored in another Tuple plus additional one.
  237. template <typename Tuple,
  238. typename T,
  239. std::size_t I = 0,
  240. std::size_t N = size<Tuple>::value>
  241. struct push_back_bt
  242. {
  243. typedef
  244. boost::tuples::cons<
  245. typename element<I, Tuple>::type,
  246. typename push_back_bt<Tuple, T, I+1, N>::type
  247. > type;
  248. static type apply(Tuple const& tup, T const& t)
  249. {
  250. return
  251. type(
  252. geometry::tuples::get<I>(tup),
  253. push_back_bt<Tuple, T, I+1, N>::apply(tup, t)
  254. );
  255. }
  256. };
  257. template <typename Tuple, typename T, std::size_t N>
  258. struct push_back_bt<Tuple, T, N, N>
  259. {
  260. typedef boost::tuples::cons<T, boost::tuples::null_type> type;
  261. static type apply(Tuple const&, T const& t)
  262. {
  263. return type(t, boost::tuples::null_type());
  264. }
  265. };
  266. template <typename Tuple, typename T>
  267. struct push_back
  268. : push_back_bt<Tuple, T>
  269. {};
  270. template <typename F, typename S, typename T>
  271. struct push_back<std::pair<F, S>, T>
  272. {
  273. typedef std::tuple<F, S, T> type;
  274. static type apply(std::pair<F, S> const& p, T const& t)
  275. {
  276. return type(p.first, p.second, t);
  277. }
  278. static type apply(std::pair<F, S> && p, T const& t)
  279. {
  280. return type(std::move(p.first), std::move(p.second), t);
  281. }
  282. static type apply(std::pair<F, S> && p, T && t)
  283. {
  284. return type(std::move(p.first), std::move(p.second), std::move(t));
  285. }
  286. };
  287. template <typename Is, typename Tuple, typename T>
  288. struct push_back_st;
  289. template <std::size_t ...Is, typename ...Ts, typename T>
  290. struct push_back_st<std::index_sequence<Is...>, std::tuple<Ts...>, T>
  291. {
  292. typedef std::tuple<Ts..., T> type;
  293. static type apply(std::tuple<Ts...> const& tup, T const& t)
  294. {
  295. return type(std::get<Is>(tup)..., t);
  296. }
  297. static type apply(std::tuple<Ts...> && tup, T const& t)
  298. {
  299. return type(std::move(std::get<Is>(tup))..., t);
  300. }
  301. static type apply(std::tuple<Ts...> && tup, T && t)
  302. {
  303. return type(std::move(std::get<Is>(tup))..., std::move(t));
  304. }
  305. };
  306. template <typename ...Ts, typename T>
  307. struct push_back<std::tuple<Ts...>, T>
  308. : push_back_st
  309. <
  310. std::make_index_sequence<sizeof...(Ts)>,
  311. std::tuple<Ts...>,
  312. T
  313. >
  314. {};
  315. }}} // namespace boost::geometry::tuples
  316. #endif // BOOST_GEOMETRY_UTIL_TUPLES_HPP