tuple.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*!
  2. @file
  3. Adapts `boost::tuple` for use with Hana.
  4. Copyright Louis Dionne 2013-2022
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_EXT_BOOST_TUPLE_HPP
  9. #define BOOST_HANA_EXT_BOOST_TUPLE_HPP
  10. #include <boost/hana/bool.hpp>
  11. #include <boost/hana/config.hpp>
  12. #include <boost/hana/detail/decay.hpp>
  13. #include <boost/hana/fwd/at.hpp>
  14. #include <boost/hana/fwd/core/make.hpp>
  15. #include <boost/hana/fwd/core/tag_of.hpp>
  16. #include <boost/hana/fwd/drop_front.hpp>
  17. #include <boost/hana/fwd/is_empty.hpp>
  18. #include <boost/hana/fwd/length.hpp>
  19. #include <boost/hana/integral_constant.hpp>
  20. #include <boost/tuple/tuple.hpp>
  21. #include <cstddef>
  22. #include <utility>
  23. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  24. namespace boost {
  25. //! @ingroup group-ext-boost
  26. //! Adapter for `boost::tuple`s.
  27. //!
  28. //!
  29. //! Modeled concepts
  30. //! ----------------
  31. //! A `boost::tuple` is a model of the `Sequence` concept, and all the
  32. //! concepts it refines. That makes it essentially the same as a Hana
  33. //! tuple, although the complexity of some operations might differ from
  34. //! that of Hana's tuple.
  35. //!
  36. //! @include example/ext/boost/tuple.cpp
  37. template <typename ...T>
  38. struct tuple { };
  39. }
  40. #endif
  41. namespace boost { namespace hana {
  42. namespace ext { namespace boost { struct tuple_tag; }}
  43. template <typename ...Xs>
  44. struct tag_of<boost::tuple<Xs...>> {
  45. using type = ext::boost::tuple_tag;
  46. };
  47. template <typename H, typename T>
  48. struct tag_of<boost::tuples::cons<H, T>> {
  49. using type = ext::boost::tuple_tag;
  50. };
  51. template <>
  52. struct tag_of<boost::tuples::null_type> {
  53. using type = ext::boost::tuple_tag;
  54. };
  55. //////////////////////////////////////////////////////////////////////////
  56. // Iterable
  57. //////////////////////////////////////////////////////////////////////////
  58. template <>
  59. struct at_impl<ext::boost::tuple_tag> {
  60. template <typename Xs, typename N>
  61. static constexpr decltype(auto) apply(Xs&& xs, N const&) {
  62. constexpr std::size_t n = N::value;
  63. return static_cast<Xs&&>(xs).template get<n>();
  64. }
  65. };
  66. template <>
  67. struct drop_front_impl<ext::boost::tuple_tag> {
  68. template <std::size_t n, typename Xs, std::size_t ...i>
  69. static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
  70. return hana::make<ext::boost::tuple_tag>(
  71. hana::at_c<n + i>(static_cast<Xs&&>(xs))...
  72. );
  73. }
  74. template <typename Xs, typename N>
  75. static constexpr auto apply(Xs&& xs, N const&) {
  76. constexpr std::size_t n = N::value;
  77. constexpr std::size_t len = decltype(hana::length(xs))::value;
  78. return drop_front_helper<n>(static_cast<Xs&&>(xs),
  79. std::make_index_sequence<(n < len ? len - n : 0)>{});
  80. }
  81. };
  82. template <>
  83. struct is_empty_impl<ext::boost::tuple_tag> {
  84. static constexpr auto apply(boost::tuples::null_type const&)
  85. { return hana::true_c; }
  86. template <typename H, typename T>
  87. static constexpr auto apply(boost::tuples::cons<H, T> const&)
  88. { return hana::false_c; }
  89. };
  90. //////////////////////////////////////////////////////////////////////////
  91. // Foldable
  92. //////////////////////////////////////////////////////////////////////////
  93. template <>
  94. struct length_impl<ext::boost::tuple_tag> {
  95. template <typename Xs>
  96. static constexpr auto apply(Xs const&) {
  97. return hana::size_c<boost::tuples::length<Xs>::value>;
  98. }
  99. };
  100. //////////////////////////////////////////////////////////////////////////
  101. // Sequence
  102. //////////////////////////////////////////////////////////////////////////
  103. template <>
  104. struct Sequence<ext::boost::tuple_tag> {
  105. static constexpr bool value = true;
  106. };
  107. template <>
  108. struct make_impl<ext::boost::tuple_tag> {
  109. template <typename ...Xs>
  110. static constexpr auto apply(Xs&& ...xs) {
  111. return boost::tuples::tuple<
  112. typename detail::decay<Xs>::type...
  113. >{static_cast<Xs&&>(xs)...};
  114. }
  115. };
  116. }} // end namespace boost::hana
  117. #endif // !BOOST_HANA_EXT_BOOST_TUPLE_HPP