linearize.hpp
ふと思い立ったので書いてみた。
ネストされたMPLのシーケンスを、
一つのシーケンスに直線化(?)するメタ関数。
- linearize.hpp
#ifndef SPRIG_TMP_LINEARIZE_HPP #define SPRIG_TMP_LINEARIZE_HPP #include <sprig/config/config.hpp> #ifdef SPRIG_USING_PRAGMA_ONCE # pragma once #endif // #ifdef SPRIG_USING_PRAGMA_ONCE #include <boost/mpl/identity.hpp> #include <boost/mpl/is_sequence.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/deref.hpp> #include <boost/mpl/inserter.hpp> #include <boost/mpl/back_inserter.hpp> #include <boost/mpl/fold.hpp> #include <boost/mpl/eval_if.hpp> #include <boost/mpl/lambda.hpp> namespace sprig { namespace tmp { // // linearize // template< typename Sequence, typename Inserter = boost::mpl::back_inserter<boost::mpl::vector0<> > > struct linearize : public boost::mpl::fold< Sequence, typename Inserter::state, boost::mpl::eval_if< boost::mpl::is_sequence<boost::mpl::_2>, linearize< boost::mpl::_2, boost::mpl::identity< boost::mpl::inserter< boost::mpl::_1, typename Inserter::operation > > >, typename Inserter::operation::template apply< boost::mpl::_1, boost::mpl::_2 > > > {}; } // namespace tmp } // namespace sprig #endif // #ifndef SPRIG_TMP_LINEARIZE_HPP
テスト。
- test-linearize.cpp
#include <boost/mpl/vector.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/assert.hpp> #include <sprig/tmp/linearize.hpp> typedef boost::mpl::vector< short, int, long, long long, __int8, __int16, __int32, __int64, unsigned short, unsigned, unsigned long, unsigned long long, unsigned __int8, unsigned __int16, unsigned __int32, unsigned __int64, float, double, long double, void > sequence_t; typedef boost::mpl::vector< boost::mpl::vector< short, int, long, long long >, __int8, __int16, __int32, __int64, boost::mpl::vector< boost::mpl::vector< unsigned short, unsigned, unsigned long, unsigned long long >, unsigned __int8, unsigned __int16, unsigned __int32, unsigned __int64 >, boost::mpl::vector< boost::mpl::vector< float, double, long double > >, void > nested_sequence_t; typedef sprig::tmp::linearize<nested_sequence_t>::type linearized_t; BOOST_MPL_ASSERT(( boost::mpl::equal<linearized_t, sequence_t> ));
MPLライクなアルゴリズムを書いたことは大してないので、
効率的なコードはたぶん書けていない。
これとは逆に、MPLシーケンスの要素数の制限を何とかするために
シーケンスを多次元のシーケンスに変換&それを一つのシーケンスとして扱うViewを生成
みたいな処理のほうが実用では必要になるかも。