さて、インデントを保つにはどうすれば良いのか。それには、ファイルイテレーションと呼ばれている方法を用いるのだが、いやはや、なんとも解説しがたいコードではある。
#if !BOOST_PP_IS_ITERATING
#ifndef HITO_FUNCTION_TRAITS
#define HITO_FUNCTION_TRAITS
#ifndef FUNCTION_MAX_ARITY
#define FUNCTION_MAX_ARITY 15
#endif // #ifndef FUNCTION_MAX_ARITY
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
// Primary Template class
template < typename Signature >
struct function_traits ;
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, FUNCTION_MAX_ARITY, "function_traits.hpp"))
#include BOOST_PP_ITERATE()
#endif //#ifndef HITO_FUNCTION_TRAITS
#elif BOOST_PP_ITERATION_DEPTH() == 1 // #if !BOOST_PP_IS_ITERATING
#define n BOOST_PP_ITERATION()
template < typename R BOOST_PP_ENUM_TRAILING_PARAMS(n, typename T) >
struct function_traits< R( BOOST_PP_ENUM_PARAMS(n, T) ) >
{
typedef R return_type ;
static int const number_of_aritys = n ;
#if n != 0
#define BOOST_PP_ITERATION_PARAMS_2 (3, (0, n-1, "function_traits.hpp"))
#include BOOST_PP_ITERATE()
#endif
} ;
#undef n
#elif BOOST_PP_ITERATION_DEPTH() == 2 // #if !BOOST_PP_IS_ITERATING
#define n BOOST_PP_ITERATION()
typedef BOOST_PP_CAT(T, n) BOOST_PP_CAT(Arg, n) ;
#undef n
#endif // #if !BOOST_PP_IS_ITERATING
しかし、ためしにVCのコンパイラにプリプロセスさせてみると、恐ろしく大量の改行を吐く。これでは意味がない。試みに、前回のコードを多少手直ししてみると。
#ifndef HITO_FUNCTION_TRAITS
#define HITO_FUNCTION_TRAITS
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#ifndef FUNCTION_MAX_ARITY
#define FUNCTION_MAX_ARITY 15
#endif // #ifndef FUNCTION_MAX_ARITY
template < typename Signature >
struct function_traits ;
#define HITO_arg_typedef(z, n, unused) \
typedef BOOST_PP_CAT(T, n) BOOST_PP_CAT(Arg, n) ;
#define HITO_function_traits(z, n, unused) \
template < typename R BOOST_PP_ENUM_TRAILING_PARAMS(n, typename T) > \
struct function_traits< R ( BOOST_PP_ENUM_PARAMS(n, T) ) > \
{ \
typedef R return_type ; \
static int const number_of_aritys = n ; \
BOOST_PP_REPEAT(n, HITO_function_typedef, ~) \
} ;
BOOST_PP_REPEAT(FUNCTION_MAX_ARITY, HITO_function_traits, ~)
#undef HITO_function_traits
#undef HITO_arg_typedef
#endif //#ifndef HITO_FUNCTION_TRAITS
こちらの方が分かりやすい。何しろ、Boostの素晴らしいプリプロセッサライブラリのおかげで、リピートのネストというものを意識しないでいい。コンパイル速度向上の点から言えば、実はマクロのz引数を利用したほうがいいのだが、最近のハードウェアはだいぶ早いし、特に意識する必要も無い。
もう変態すぎて私には理解できませんw
ReplyDelete本当に、Boostには色々なものがあるものですね! 感動しました。
変態というより、力技です。
ReplyDelete