2009年2月21日土曜日

swig のはずが boost preprocessor

 swig で boost::random をラッピングしたクラスを作ってみようと、あれこれ構想しているうちに、何故か脱線してしまい。boost preprocessor に夢中になってしまった。そもそも、こういう方向性でいいのかどうか7割ぐらいの確信でもって、どんどん突っ走ってしまっていいのだろうか?という一抹の不安もぬぐえない…。が、能天気な性格なのでよしとする。

 プリプロセッサも面白いね。


#include <iostream>
#include <typeinfo>
#include <fstream>
#include <boost/preprocessor.hpp>
#include <boost/random.hpp>

#define RANDOM_TYPE_COUNT 16
#define RANDOM_TYPE_ARRAY ( RANDOM_TYPE_COUNT, ( \
minstd_rand, \
rand48, \
ecuyer1988, \
kreutzer1986, \
hellekalek1995, \
mt11213b, \
mt19937, \
lagged_fibonacci607, \
lagged_fibonacci1279, \
lagged_fibonacci2281, \
lagged_fibonacci3217, \
lagged_fibonacci4423, \
lagged_fibonacci9689, \
lagged_fibonacci19937, \
lagged_fibonacci23209, \
lagged_fibonacci44497 \
) )

#define INC_OP( r, i ) BOOST_PP_INC(i)
#define PRED( r, i ) BOOST_PP_LESS(i,RANDOM_TYPE_COUNT)


#define PRINT_TYPE( r, i ) { \
ofs << "struct " << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY)) << " {\n"; \
ofs << " char pod[" << sizeof(BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY)) << "];\n"; \
ofs << "};\n" << std::endl; \
ofs << "struct valiate_generator_" << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY)) << " {\n"; \
ofs << " char pod[" << sizeof(variate_generator<BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY),uniform_real<> >) << "];\n"; \
ofs << "};\n" << std::endl; \
}

#define PRINT_RETYPE( r, i ) { \
ofs << "typedef variate_generator< " << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY)) << ", uniform_real<> >"; \
ofs << " variate_generator_" << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY)) << ";\n"; \
}


#define PRINT_CLASS( r, i ) { \
ofs << "class algo_" << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY)) << " {\n"; \
ofs << "private:\n"; \
ofs << " " << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY)) << " generator_;\n"; \
ofs << " variate_generator_" << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY)) << " variater_;\n"; \
ofs << "public:\n"; \
ofs << " algo_" << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY)) << "( unsigned int32 seed ); \n"; \
ofs << " double random(); \n"; \
ofs << " " << typeid( BOOST_PP_ARRAY_ELEM(i,RANDOM_TYPE_ARRAY)::result_type ).name() << " numric_random();\n"; \
ofs << "};\n" << std::endl; \
}


using namespace boost;

void print_random_def() {
std::ofstream ofs( "random_def.hpp" );

ofs << "// random_def.hpp\n";

BOOST_PP_FOR( 0, PRED, INC_OP, PRINT_TYPE )

ofs << "struct uniform_base {\n";
ofs << " char pod[" << sizeof(uniform_real<>) << "];\n";
ofs << "};\n";

}

void print_random_retype() {
std::ofstream ofs( "random_retype.hpp" );

ofs << "#include <boost/random.hpp>\n";
ofs << "using namespace boost;\n";

BOOST_PP_FOR( 0, PRED, INC_OP, PRINT_RETYPE )

ofs << "typedef uniform_real<> uniform_base;" << std::endl;

}

void print_random_hpp() {
std::ofstream ofs( "random.hpp" );

ofs << "#ifdef SWIG\n";
ofs << "#include \"random_def.hpp\"\n";
ofs << "#else\n";
ofs << "#include \"random_retype.hpp\"\n";
ofs << "#endif\n";
ofs << "\n";

BOOST_PP_FOR( 0, PRED, INC_OP, PRINT_CLASS )
}

int main() {

print_random_def();

print_random_retype();

print_random_hpp();

return 0;
}

0 件のコメント: