Back to home page

EIC code displayed by LXR

 
 

    


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 //  Copyright 2015-2020 Peter Dimov.
0005 //
0006 //  Distributed under the Boost Software License, Version 1.0.
0007 //
0008 //  See accompanying file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt
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 ) // unreferenced formal parameter 'tp'
0023 #endif
0024 
0025 namespace boost
0026 {
0027 namespace mp11
0028 {
0029 
0030 // tuple_apply
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 } // namespace detail
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 // construct_from_tuple
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 } // namespace detail
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 // tuple_for_each
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 && /*tp*/, integer_sequence<std::size_t>, F && f )
0081 {
0082     return std::forward<F>(f);
0083 }
0084 
0085 } // namespace detail
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 // tuple_transform
0094 
0095 namespace detail
0096 {
0097 
0098 // std::forward_as_tuple is not constexpr in C++11 or libstdc++ 5.x
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 // !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
0149 
0150 } // namespace detail
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 // BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
0175 
0176 } // namespace mp11
0177 } // namespace boost
0178 
0179 #if BOOST_MP11_MSVC
0180 # pragma warning( pop )
0181 #endif
0182 
0183 #endif // #ifndef BOOST_TUPLE_HPP_INCLUDED