1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
#include <iostream>
#include <type_traits>
template< typename T, T... VALUES > struct seq_c { using value_type = T ; };
template< typename T, T... > struct size ;
template< typename T, T... VALUES > struct size< seq_c< T, VALUES...> >
{ static constexpr std::size_t value = sizeof...(VALUES) ; } ;
template< typename T > struct pop_front {} ;
template< typename T, T V, T... VALUES > struct pop_front< seq_c< T, V, VALUES...> >
{ using type = seq_c< T, VALUES...> ; } ;
template< std::size_t N, typename T > struct at {} ;
template< std::size_t N, typename T, T V, T... VALUES > struct at< N, seq_c< T, V, VALUES...> >
{ static constexpr T value = at<N-1, typename pop_front< seq_c< T, V, VALUES...> >::type >::value ; } ;
template< typename T, T V, T... VALUES > struct at< 0, seq_c< T, V, VALUES...> >
{ static constexpr T value = V ; } ;
template< typename T > struct front
{ static constexpr typename T::value_type value = at<0,T>::value ; } ;
template< typename T, T V, typename U > struct push_back {} ;
template< typename T, T V > struct push_back< T, V, seq_c<T> >
{ using type = seq_c<T,V> ; } ;
template< typename T, T V, T... VALUES > struct push_back< T, V, seq_c< T, VALUES...> >
{ using type = seq_c< T, VALUES..., V > ; } ;
template < typename T, typename U, std::size_t N = size<T>::value > struct paiwise_sum
{
using common_type = typename std::common_type< typename T::value_type,
typename U::value_type >::type ;
using type = typename push_back<
common_type,
front<T>::value + front<U>::value,
typename paiwise_sum< typename pop_front<T>::type,
typename pop_front<U>::type >::type >::type ;
};
template < typename T, typename U > struct paiwise_sum<T,U,0>
{
using type = seq_c< typename std::common_type< typename T::value_type,
typename U::value_type >::type > ; };
template < typename T, T A, T B > struct max
{ static constexpr T value = A < B ? B : A ; } ;
template< typename T > struct max_element {};
template< typename T, T V, T... VALUES > struct max_element< seq_c< T, V, VALUES...> >
{
using value_type = typename seq_c< T, V, VALUES...>::value_type ;
static constexpr T value = max< T, V, max_element< seq_c< T, VALUES...> >::value >::value ;
} ;
template< typename T, T V > struct max_element< seq_c< T, V > > { static constexpr T value = V ; } ;
template < typename T > struct print {} ;
template < typename T > struct print< seq_c<T> > {};
template< typename T, T V, T... VALUES >
struct print< seq_c< T, V, VALUES...> > : print< seq_c<T,VALUES...> >
{ print() { std::cout << V << ' ' ; } } ;
int main()
{
using a = seq_c< long long , 10, 20, 30, 40, 50 > ;
using b = seq_c< int, -1, -17, -23, 0, -45 > ;
using c = paiwise_sum<a,b>::type ;
print<c>{} ;
std::cout << " max: " << max_element<c>::value << '\n' ;
}
|