マクロの可変長引数に対しての all_of, any_of, none_of アルゴリズム
最近 Boost.PP をすごく使うことが多いので
使ってる中で、欲しかったアルゴリズムを作ってみました。
マクロは個人的にはキライな方なんですが
Boost.PP くらい突き抜けるとアリだな、と思います。
#define PP_VA_ALL_OF( mac, ... ) \ BOOST_PP_EQUAL( \ BOOST_PP_SEQ_SIZE( \ BOOST_PP_SEQ_FILTER( PP_DETAIL_ALGORITHM_EXPAND, _, \ BOOST_PP_SEQ_FOR_EACH( PP_DETAIL_ALGORITHM_APPLY, mac, BOOST_PP_VARIADIC_TO_SEQ( __VA_ARGS__ ) ) \ ) \ ), \ BOOST_PP_SEQ_SIZE( BOOST_PP_VARIADIC_TO_SEQ( __VA_ARGS__ ) ) \ ) #define PP_VA_ANY_OF( mac, ... ) \ BOOST_PP_BOOL( \ BOOST_PP_SEQ_SIZE( \ BOOST_PP_SEQ_FILTER( PP_DETAIL_ALGORITHM_EXPAND, _, \ BOOST_PP_SEQ_FOR_EACH( PP_DETAIL_ALGORITHM_APPLY, mac, BOOST_PP_VARIADIC_TO_SEQ( __VA_ARGS__ ) ) \ ) \ ) \ ) #define PP_VA_NONE_OF( mac, ... ) \ BOOST_PP_NOT( \ BOOST_PP_BOOL( \ BOOST_PP_SEQ_SIZE( \ BOOST_PP_SEQ_FILTER( PP_DETAIL_ALGORITHM_EXPAND, _, \ BOOST_PP_SEQ_FOR_EACH( PP_DETAIL_ALGORITHM_APPLY, mac, BOOST_PP_VARIADIC_TO_SEQ( __VA_ARGS__ ) ) \ ) \ ) \ ) \ ) #define PP_DETAIL_ALGORITHM_APPLY( r, data, elem ) ( data( elem ) ) #define PP_DETAIL_ALGORITHM_EXPAND( r, data, elem ) elem #define ARGSa boo,foo,bar #define ARGSb ,,, #define ARGSc boo,,bar // 確認用コード // ↓出力 PP_VA_ALL_OF( BOOST_PP_IS_EMPTY, ARGSa ); // 0 PP_VA_ALL_OF( BOOST_PP_IS_EMPTY, ARGSb ); // 1 PP_VA_ALL_OF( BOOST_PP_IS_EMPTY, ARGSc ); // 0 PP_VA_ANY_OF( BOOST_PP_IS_EMPTY, ARGSa ); // 0 PP_VA_ANY_OF( BOOST_PP_IS_EMPTY, ARGSb ); // 1 PP_VA_ANY_OF( BOOST_PP_IS_EMPTY, ARGSc ); // 1 PP_VA_NONE_OF( BOOST_PP_IS_EMPTY, ARGSa ); // 1 PP_VA_NONE_OF( BOOST_PP_IS_EMPTY, ARGSb ); // 0 PP_VA_NONE_OF( BOOST_PP_IS_EMPTY, ARGSc ); // 0
本当は、PP_VA_ANY_OF が欲しくて、
「可変長引数に空引数があると
Boost.Concept でも使ってわかりやすいビルドエラーにしたい」
という感じで作りました。
マクロのエラーはテンプレのエラーよりも追いかけるのが大変なので…(^_^;)