Boost logo

Boost :

From: Daniel Wallin (daniel_at_[hidden])
Date: 2006-11-04 21:11:50


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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk