2013-11-25

久しぶりにメタプログラミングらしいメタプログラミングをした

zip

これをみて、早速実装を始めたが、残念ながらボレロ村上さんに抜かれてしまった。

ボレロ村上の実装

ボレロ村上さんのコードを参考にしたわけではないが、書き終わってから見ると、同じになっていた。

江添の実装

#include <iostream>
#include <array>
#include <tuple>
#include <cstddef>


template< std::size_t ... >
struct index_seq { } ;

template < std::size_t N, typename T >
struct make_index_seq_impl ;

template < std::size_t N, std::size_t ... I  >
struct make_index_seq_impl< N, index_seq< I ... > >
{
    using type = typename make_index_seq_impl< N-1, index_seq< N-1, I... > >::type ;
} ;


template < std::size_t ... I  > 
struct make_index_seq_impl< 0, index_seq< I ... > >
{
    using type = index_seq< I... > ;
} ;

template< std::size_t N >
using make_index_seq = typename make_index_seq_impl< N , index_seq< > >::type ;

template < std::size_t I, std::size_t N, typename ... Types >
constexpr auto make_unpacked_tuple( std::array< Types, N > const & ... containers )
    -> std::tuple< Types ... >
{
    return std::make_tuple( containers[I]... ) ;
}

template < std::size_t N, std::size_t ... I, typename ... Types >
constexpr auto zip_aux( index_seq< I ... >, std::array< Types, N > const & ... containers )
    -> std::array< std::tuple< Types... >, N >
{
    return std::array< std::tuple< Types ... >, N >{ { make_unpacked_tuple<I>( containers... )... } } ;
} 

template < std::size_t N, typename ... Types >
constexpr auto zip( std::array< Types, N > const & ... containers )
    -> std::array< std::tuple< Types... >, N >
{
    return zip_aux( make_index_seq< N >(), containers ... ) ;
}

int main()
{
    constexpr std::array<int, 5>  a = { { 1, 2, 3, 4, 5 } };
    constexpr std::array<char, 5> b = { { 'a', 'b', 'c', 'd', 'e' } };

    auto c = zip<5>(a, b) ;


    for ( auto const & i : c )
    {
        std::cout << std::get<0>(i) << " , " << std::get<1>(i) << '\n' ;
    }
}

なお、ここで使っているindex_seqは、今、標準ライブラリに提案されている。

本の虫: C++ 2013-01 mailingの簡易レビュー

ちなみに、これはコンパイル時実行にこだわっているからこうなるのであって、実行時実行なら、普通に以下のように書ける。

zip.cpp

No comments:

Post a Comment

You can use some HTML elements, such as <b>, <i>, <a>, also, some characters need to be entity referenced such as <, > and & Your comment may need to be confirmed by blog author. Your comment will be published under GFDL 1.3 or later license with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.