tuple.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright Oliver Kowalke 2014.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_CONTEXT_DETAIL_TUPLE_H
  6. #define BOOST_CONTEXT_DETAIL_TUPLE_H
  7. #include <tuple>
  8. #include <utility>
  9. #include <boost/config.hpp>
  10. #include <boost/context/detail/config.hpp>
  11. #include <boost/context/detail/index_sequence.hpp>
  12. #ifdef BOOST_HAS_ABI_HEADERS
  13. # include BOOST_ABI_PREFIX
  14. #endif
  15. namespace boost {
  16. namespace context {
  17. namespace detail {
  18. template< typename ... S, typename ... T, std::size_t ... I >
  19. void
  20. head_impl( std::tuple< S ... > & s,
  21. std::tuple< T ... > & t, index_sequence< I ... >) {
  22. t = std::tuple< T ... >{ std::get< I >( s) ... };
  23. }
  24. template< typename ... S, typename ... T, std::size_t ... I >
  25. void
  26. head_impl( std::tuple< S ... > && s,
  27. std::tuple< T ... > & t, index_sequence< I ... >) {
  28. t = std::tuple< T ... >{ std::get< I >( std::move( s) ) ... };
  29. }
  30. template< typename ... S, std::size_t ... I1, typename ... T, std::size_t ... I2 >
  31. void
  32. tail_impl( std::tuple< S ... > & s, index_sequence< I1 ... >,
  33. std::tuple< T ... > & t, index_sequence< I2 ... >) {
  34. constexpr std::size_t Idx = (sizeof...(I1)) - (sizeof...(I2));
  35. t = std::tuple< T ... >{ std::get< (Idx + I2) >( s) ... };
  36. }
  37. template< typename ... S, std::size_t ... I1, typename ... T, std::size_t ... I2 >
  38. void
  39. tail_impl( std::tuple< S ... > && s, index_sequence< I1 ... >,
  40. std::tuple< T ... > & t, index_sequence< I2 ... >) {
  41. constexpr std::size_t Idx = (sizeof...(I1)) - (sizeof...(I2));
  42. t = std::tuple< T ... >{ std::get< (Idx + I2) >( std::move( s) ) ... };
  43. }
  44. template< typename ... T >
  45. class tuple_head;
  46. template< typename ... T >
  47. class tuple_head< std::tuple< T ... > > {
  48. private:
  49. std::tuple< T ... > & t_;
  50. public:
  51. tuple_head( std::tuple< T ... > & t) noexcept :
  52. t_( t) {
  53. }
  54. template< typename ... S >
  55. void operator=( std::tuple< S ... > & s) {
  56. static_assert((sizeof...(T)) <= (sizeof...(S)), "invalid tuple size");
  57. head_impl( s,
  58. t_, index_sequence_for< T ... >{} );
  59. }
  60. template< typename ... S >
  61. void operator=( std::tuple< S ... > && s) {
  62. static_assert((sizeof...(T)) <= (sizeof...(S)), "invalid tuple size");
  63. head_impl( std::move( s),
  64. t_, index_sequence_for< T ... >{} );
  65. }
  66. };
  67. template< typename ... T >
  68. class tuple_tail;
  69. template< typename ... T >
  70. class tuple_tail< std::tuple< T ... > > {
  71. private:
  72. std::tuple< T ... > & t_;
  73. public:
  74. tuple_tail( std::tuple< T ... > & t) noexcept :
  75. t_( t) {
  76. }
  77. template< typename ... S >
  78. void operator=( std::tuple< S ... > & s) {
  79. static_assert((sizeof...(T)) <= (sizeof...(S)), "invalid tuple size");
  80. tail_impl( s, index_sequence_for< S ... >{},
  81. t_, index_sequence_for< T ... >{} );
  82. }
  83. template< typename ... S >
  84. void operator=( std::tuple< S ... > && s) {
  85. static_assert((sizeof...(T)) <= (sizeof...(S)), "invalid tuple size");
  86. tail_impl( std::move( s), index_sequence_for< S ... >{},
  87. t_, index_sequence_for< T ... >{} );
  88. }
  89. };
  90. template< typename ... T >
  91. detail::tuple_head< std::tuple< T ... > >
  92. head( std::tuple< T ... > & tpl) {
  93. return tuple_head< std::tuple< T ... > >{ tpl };
  94. }
  95. template< typename ... T >
  96. detail::tuple_tail< std::tuple< T ... > >
  97. tail( std::tuple< T ... > & tpl) {
  98. return tuple_tail< std::tuple< T ... > >{ tpl };
  99. }
  100. }}}
  101. #ifdef BOOST_HAS_ABI_HEADERS
  102. #include BOOST_ABI_SUFFIX
  103. #endif
  104. #endif // BOOST_CONTEXT_DETAIL_TUPLE_H