tuple.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #ifndef BOOST_MP11_TUPLE_HPP_INCLUDED
  2. #define BOOST_MP11_TUPLE_HPP_INCLUDED
  3. // Copyright 2015, 2017 Peter Dimov.
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. //
  7. // See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt
  9. #include <boost/mp11/integer_sequence.hpp>
  10. #include <boost/mp11/detail/config.hpp>
  11. #include <tuple>
  12. #include <utility>
  13. #include <type_traits>
  14. #include <cstddef>
  15. #if BOOST_MP11_MSVC
  16. # pragma warning( push )
  17. # pragma warning( disable: 4100 ) // unreferenced formal parameter 'tp'
  18. #endif
  19. namespace boost
  20. {
  21. namespace mp11
  22. {
  23. // tuple_apply
  24. namespace detail
  25. {
  26. template<class F, class Tp, std::size_t... J> BOOST_MP11_CONSTEXPR auto tuple_apply_impl( F && f, Tp && tp, integer_sequence<std::size_t, J...> )
  27. -> decltype( std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... ) )
  28. {
  29. return std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... );
  30. }
  31. } // namespace detail
  32. template<class F, class Tp,
  33. class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
  34. BOOST_MP11_CONSTEXPR auto tuple_apply( F && f, Tp && tp )
  35. -> decltype( detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() ) )
  36. {
  37. return detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() );
  38. }
  39. // construct_from_tuple
  40. namespace detail
  41. {
  42. template<class T, class Tp, std::size_t... J> BOOST_MP11_CONSTEXPR T construct_from_tuple_impl( Tp && tp, integer_sequence<std::size_t, J...> )
  43. {
  44. return T( std::get<J>(std::forward<Tp>(tp))... );
  45. }
  46. } // namespace detail
  47. template<class T, class Tp,
  48. class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
  49. BOOST_MP11_CONSTEXPR T construct_from_tuple( Tp && tp )
  50. {
  51. return detail::construct_from_tuple_impl<T>( std::forward<Tp>(tp), Seq() );
  52. }
  53. // tuple_for_each
  54. namespace detail
  55. {
  56. template<class Tp, std::size_t... J, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence<std::size_t, J...>, F && f )
  57. {
  58. using A = int[sizeof...(J)];
  59. return (void)A{ ((void)f(std::get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f);
  60. }
  61. template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && /*tp*/, integer_sequence<std::size_t>, F && f )
  62. {
  63. return std::forward<F>(f);
  64. }
  65. } // namespace detail
  66. template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each( Tp && tp, F && f )
  67. {
  68. using seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>;
  69. return detail::tuple_for_each_impl( std::forward<Tp>(tp), seq(), std::forward<F>(f) );
  70. }
  71. } // namespace mp11
  72. } // namespace boost
  73. #if BOOST_MP11_MSVC
  74. # pragma warning( pop )
  75. #endif
  76. #endif // #ifndef BOOST_TUPLE_HPP_INCLUDED