
Eric Niebler wrote:
I'd still be curious what a PP solution looks like, though. The problem stumped me for quite some time.
I'll bite. It's a bit of a hack, but it works. :) It basically accumulates the closing >'s as it goes, and expands them after the last item. It keeps a looping counter that keeps track of when to split into another mpl::and_<>. #include <boost/preprocessor/for.hpp> #include <boost/preprocessor/if.hpp> #include <boost/preprocessor/empty.hpp> #include <boost/preprocessor/dec.hpp> #include <boost/preprocessor/tuple/elem.hpp> #include <boost/preprocessor/punctuation/comma.hpp> #include <boost/preprocessor/arithmetic/div.hpp> #include <boost/preprocessor/logical/or.hpp> #include <boost/preprocessor/logical/not.hpp> #define MAKE_PREDICATE(z, n, data) \ BOOST_PP_CAT(pred,n) #define PREDICATE(r, state) \ BOOST_PP_TUPLE_ELEM(3,0,state) #define OP0(r, state, m) \ ( \ BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(3,0,state)) \ , m \ , BOOST_PP_TUPLE_ELEM(3,2,state) \ BOOST_PP_IF( \ BOOST_PP_OR( \ m \ , BOOST_PP_NOT( \ BOOST_PP_DEC( \ BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(3,0,state)) \ ) \ ) \ ) \ , BOOST_PP_EMPTY \ , > BOOST_PP_EMPTY \ )() \ ) #define OP(r, state) \ OP0( \ r \ , state \ , BOOST_PP_IF( \ BOOST_PP_TUPLE_ELEM(3,1,state) \ , BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(3,1,state)) \ , 2 \ ) \ ) #define M(r, state) \ BOOST_PP_IF( \ BOOST_PP_OR( \ BOOST_PP_TUPLE_ELEM(3,1,state) \ , BOOST_PP_NOT( \ BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(3,0,state)) \ ) \ ) \ , BOOST_PP_EMPTY \ , mpl::and_< BOOST_PP_EMPTY \ )() \ MAKE_PREDICATE( \ 0, BOOST_PP_TUPLE_ELEM(3,0,state), ~ \ ) \ BOOST_PP_IF( \ BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(3,0,state)) \ , BOOST_PP_COMMA \ , BOOST_PP_TUPLE_ELEM(3,2,state) BOOST_PP_EMPTY \ )() // for n >= 2 #define PREDICATE_LIST(n) \ BOOST_PP_FOR( \ (n,0,>) \ , PREDICATE \ , OP \ , M \ ) PREDICATE_LIST(2) PREDICATE_LIST(3) PREDICATE_LIST(4) PREDICATE_LIST(5) PREDICATE_LIST(6) PREDICATE_LIST(7) PREDICATE_LIST(8) -- Daniel Wallin Boost Consulting www.boost-consulting.com