File indexing completed on 2025-01-30 09:46:52
0001 #ifndef BOOST_MP11_TUPLE_HPP_INCLUDED
0002 #define BOOST_MP11_TUPLE_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <boost/mp11/integer_sequence.hpp>
0012 #include <boost/mp11/list.hpp>
0013 #include <boost/mp11/function.hpp>
0014 #include <boost/mp11/detail/config.hpp>
0015 #include <tuple>
0016 #include <utility>
0017 #include <type_traits>
0018 #include <cstddef>
0019
0020 #if BOOST_MP11_MSVC
0021 # pragma warning( push )
0022 # pragma warning( disable: 4100 )
0023 #endif
0024
0025 namespace boost
0026 {
0027 namespace mp11
0028 {
0029
0030
0031 namespace detail
0032 {
0033
0034 using std::get;
0035
0036 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...> )
0037 -> decltype( std::forward<F>(f)( get<J>(std::forward<Tp>(tp))... ) )
0038 {
0039 return std::forward<F>(f)( get<J>(std::forward<Tp>(tp))... );
0040 }
0041
0042 }
0043
0044 template<class F, class Tp,
0045 class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
0046 BOOST_MP11_CONSTEXPR auto tuple_apply( F && f, Tp && tp )
0047 -> decltype( detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() ) )
0048 {
0049 return detail::tuple_apply_impl( std::forward<F>(f), std::forward<Tp>(tp), Seq() );
0050 }
0051
0052
0053 namespace detail
0054 {
0055
0056 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...> )
0057 {
0058 return T( get<J>(std::forward<Tp>(tp))... );
0059 }
0060
0061 }
0062
0063 template<class T, class Tp,
0064 class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>>
0065 BOOST_MP11_CONSTEXPR T construct_from_tuple( Tp && tp )
0066 {
0067 return detail::construct_from_tuple_impl<T>( std::forward<Tp>(tp), Seq() );
0068 }
0069
0070
0071 namespace detail
0072 {
0073
0074 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 )
0075 {
0076 using A = int[sizeof...(J)];
0077 return (void)A{ ((void)f(get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f);
0078 }
0079
0080 template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && , integer_sequence<std::size_t>, F && f )
0081 {
0082 return std::forward<F>(f);
0083 }
0084
0085 }
0086
0087 template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each( Tp && tp, F && f )
0088 {
0089 using seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>;
0090 return detail::tuple_for_each_impl( std::forward<Tp>(tp), seq(), std::forward<F>(f) );
0091 }
0092
0093
0094
0095 namespace detail
0096 {
0097
0098
0099 template<class... T> BOOST_MP11_CONSTEXPR auto tp_forward_r( T&&... t ) -> std::tuple<T&&...>
0100 {
0101 return std::tuple<T&&...>( std::forward<T>( t )... );
0102 }
0103
0104 template<class... T> BOOST_MP11_CONSTEXPR auto tp_forward_v( T&&... t ) -> std::tuple<T...>
0105 {
0106 return std::tuple<T...>( std::forward<T>( t )... );
0107 }
0108
0109 template<std::size_t J, class... Tp>
0110 BOOST_MP11_CONSTEXPR auto tp_extract( Tp&&... tp )
0111 -> decltype( tp_forward_r( get<J>( std::forward<Tp>( tp ) )... ) )
0112 {
0113 return tp_forward_r( get<J>( std::forward<Tp>( tp ) )... );
0114 }
0115
0116 #if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
0117
0118 template<class F, class... Tp, std::size_t... J>
0119 BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp&&... tp )
0120 -> decltype( tp_forward_v( tuple_apply( f, tp_extract<J>( std::forward<Tp>(tp)... ) )... ) )
0121 {
0122 return tp_forward_v( tuple_apply( f, tp_extract<J>( std::forward<Tp>(tp)... ) )... );
0123 }
0124
0125 #else
0126
0127 template<class F, class Tp1, std::size_t... J>
0128 BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1 )
0129 -> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ) )... ) )
0130 {
0131 return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ) )... );
0132 }
0133
0134 template<class F, class Tp1, class Tp2, std::size_t... J>
0135 BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1, Tp2&& tp2 )
0136 -> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ) )... ) )
0137 {
0138 return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ) )... );
0139 }
0140
0141 template<class F, class Tp1, class Tp2, class Tp3, std::size_t... J>
0142 BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1, Tp2&& tp2, Tp3&& tp3 )
0143 -> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ), get<J>( std::forward<Tp3>(tp3) ) )... ) )
0144 {
0145 return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ), get<J>( std::forward<Tp3>(tp3) ) )... );
0146 }
0147
0148 #endif
0149
0150 }
0151
0152 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
0153
0154 template<class F, class Tp1, class... Tp,
0155 class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp1>::type>::value>>
0156 BOOST_MP11_CONSTEXPR auto tuple_transform( F const& f, Tp1&& tp1, Tp&&... tp )
0157 -> decltype( detail::tuple_transform_impl( Seq(), f, std::forward<Tp1>(tp1), std::forward<Tp>(tp)... ) )
0158 {
0159 return detail::tuple_transform_impl( Seq(), f, std::forward<Tp1>(tp1), std::forward<Tp>(tp)... );
0160 }
0161
0162 #else
0163
0164 template<class F, class... Tp,
0165 class Z = mp_list<mp_size_t<std::tuple_size<typename std::remove_reference<Tp>::type>::value>...>,
0166 class E = mp_if<mp_apply<mp_same, Z>, mp_front<Z>>,
0167 class Seq = make_index_sequence<E::value>>
0168 BOOST_MP11_CONSTEXPR auto tuple_transform( F const& f, Tp&&... tp )
0169 -> decltype( detail::tuple_transform_impl( Seq(), f, std::forward<Tp>(tp)... ) )
0170 {
0171 return detail::tuple_transform_impl( Seq(), f, std::forward<Tp>(tp)... );
0172 }
0173
0174 #endif
0175
0176 }
0177 }
0178
0179 #if BOOST_MP11_MSVC
0180 # pragma warning( pop )
0181 #endif
0182
0183 #endif