Rokiのチラ裏

学生による学習のログ

swap of variadic templates packages

オレオレライブラリ、Srook C++ Librariesでは、Variadic templateを端的なpackで型情報を保持している。

// simply pack implemention
template<class...>
struct pack{};

かの有名なAndrew Koenig氏は、swapは基本的な操作であると述べている

よって、Variadic templateのpack操作にもswapが必要であるので書く事にした。実装は短く、とても簡単。

尚、本エントリでは、型情報の出力に一々boost::typeindex……と記述するのも怠い冗長であるので以下の関数を用いて実行結果を検証する。

#include<boost/type_index.hpp>
#include<iostream>

template<class OutputType>
void print(OutputType&&)
{
    using namespace boost::typeindex;
    std::cout<< type_id< std::decay_t<OutputType> >().pretty_name() <<std::endl;
}

さて、肝心なSwapAtは以下のように使う。

#include<srook/mpl/variadic_player.hpp>

using tp1=
    srook::mpl::make_some_pack<
        srook::mpl::pack_setting<int,2>,
        srook::mpl::pack_setting<float,3>
    >;
using tp2=
    srook::mpl::make_some_pack<
        srook::mpl::pack_setting<char,2>,
        srook::mpl::pack_setting<double,3>
    >;

// tp1とtp2のindex 1をswapしたtp1の結果
using swaped_L=srook::mpl::SwapAt_L<tp1,tp2,1>;
// tp1とtp2のindex 2をswapしたtp2の結果
using swaped_R=srook::mpl::SwapAt_R<tp1,tp2,2>;

print(swaped_L());
print(swaped_R());
srook::mpl::v1::pack<int, char, float, float, float>
srook::mpl::v1::pack<char, char, float, double, double>

単に型同士を完全にSwapするという操作は無意味である*1ため、パックの特定のインデックス同士をSwapする実装となっている。

また、上記のSwapでは、お互いに同じインデックス値の型を交換する事となるが、相違なるインデックス値でSwapしたい時もあろう。そのような時のためにSwapAt_Specifiedを書いた。

今後の機能拡張などの可能性を踏まえた上で、若干複雑な実装となっているが本質的にはとても簡単な操作である。以下のように使える。

#include<srook/mpl/variadic_player.hpp>

using tp1=srook::mpl::pack<char,int,float>;
using tp2=srook::mpl::pack<double,bool>;

// tp1のindex 0とtp2のindex 1をswapしたtp1の結果
using swaped_L=srook::mpl::SwapAt_Specified_L<tp1,0,tp2,1>;
// tp1のindex 0とtp2のindex 1をswapしたtp2の結果
using swaped_R=srook::mpl::SwapAt_Specified_R<tp1,0,tp2,1>;

print(swaped_L());
print(swaped_R());
srook::mpl::v1::pack<bool, int, float>
srook::mpl::v1::pack<double, char>

快適なSwapライフを。

*1:オブジェクトのように、パックの中身がデータとして変動するわけではないため