tuple.hpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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/config.hpp>
  11. #include <boost/config/workaround.hpp>
  12. #include <tuple>
  13. #include <utility>
  14. #include <type_traits>
  15. #include <cstddef>
  16. #if defined(BOOST_MSVC)
  17. # pragma warning( push )
  18. # pragma warning( disable: 4100 ) // unreferenced formal parameter 'tp'
  19. #endif
  20. namespace boost
  21. {
  22. namespace mp11
  23. {
  24. // tuple_apply
  25. namespace detail
  26. {
  27. template<class F, class Tp, std::size_t... J> BOOST_CONSTEXPR auto tuple_apply_impl( F && f, Tp && tp, integer_sequence<std::size_t, J...> )
  28. -> decltype( std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... ) )
  29. {
  30. return std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... );
  31. }
  32. } // namespace detail
  33. template<class F, class Tp,
  34. class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
  35. BOOST_CONSTEXPR auto tuple_apply( F && f, Tp && tp )
  36. -> decltype( detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() ) )
  37. {
  38. return detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() );
  39. }
  40. // construct_from_tuple
  41. namespace detail
  42. {
  43. template<class T, class Tp, std::size_t... J> BOOST_CONSTEXPR T construct_from_tuple_impl( Tp && tp, integer_sequence<std::size_t, J...> )
  44. {
  45. return T( std::get<J>(std::forward<Tp>(tp))... );
  46. }
  47. } // namespace detail
  48. template<class T, class Tp,
  49. class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
  50. BOOST_CONSTEXPR T construct_from_tuple( Tp && tp )
  51. {
  52. return detail::construct_from_tuple_impl<T>( std::forward<Tp>(tp), Seq() );
  53. }
  54. // tuple_for_each
  55. namespace detail
  56. {
  57. template<class Tp, std::size_t... J, class F> BOOST_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence<std::size_t, J...>, F && f )
  58. {
  59. using A = int[sizeof...(J)];
  60. return (void)A{ ((void)f(std::get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f);
  61. }
  62. template<class Tp, class F> BOOST_CONSTEXPR F tuple_for_each_impl( Tp && /*tp*/, integer_sequence<std::size_t>, F && f )
  63. {
  64. return std::forward<F>(f);
  65. }
  66. } // namespace detail
  67. template<class Tp, class F> BOOST_CONSTEXPR F tuple_for_each( Tp && tp, F && f )
  68. {
  69. using seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>;
  70. return detail::tuple_for_each_impl( std::forward<Tp>(tp), seq(), std::forward<F>(f) );
  71. }
  72. } // namespace mp11
  73. } // namespace boost
  74. #if defined(BOOST_MSVC)
  75. # pragma warning( pop )
  76. #endif
  77. #endif // #ifndef BOOST_TUPLE_HPP_INCLUDED