Search code examples
c++templatesc-preprocessormetaprogrammingboost-mpl

Converting a MPL Vector to a Static Array


I wrote some code to generate a boost::mpl::vector to use as a lookup table for a factorial function, as a test for a more general library function with which a developer may be able to generate a lookup table in the form of a static array of primitives. The function (which would most probably be implemented as a preprocessor macro definition) would accept the name and size of the array to be initialized, as well the name of a class template to be used as the metafunction to initialize each element i of the array.

I thought that the best way to go about doing this without the use of external scripts would be to

  1. Create a boost::mpl::vector, as is done in the code listing below, and push the return value of the user-supplied metafunction for each element of the array to the back of the vector;
  2. Use the elements of the vector initialize the static array (perhaps by using a series of macros, the last of which would use the __VARARGS__ macro to accomplish this).

I know neither how I would accomplish (2) nor whether the procedure I describe is a good way of doing what I seek. Here are the following questions for which I would like answers:

  1. Is my procedure a good way of accomplishing what I seek? If not, please describe a better procedure which would accomplish the same thing, without the use of external scripts.

  2. If my procedure is indeed a good way of accomplishing what I seek, how would I implement (2)?

    I will be sure to post a link to the source file containing library function which I describe once I implement it. The code listing follows below.

    namespace mpl = boost::mpl;

    template <typename x>
    struct factorial:
        mpl::if_<mpl::greater<x, mpl::int_<1>>,
            mpl::multiplies<x, factorial<x::prior>>,
            mpl::int_<1>
        >::type
    {};
    
    template <typename sequence, typename size>
    struct compileTable:
        mpl::if_<mpl::greater<size, mpl::int_<0>>,
            compileTable<
                mpl::push_front<sequence, factorial<size>>::type,
                size::prior
            >,
            sequence
        >::type
    {};
    
    static const int TABLE_SIZE = 13;
    
    typedef compileTable<
        mpl::vector<>,
        mpl::int_<TABLE_SIZE>
    >::type factorialTable;
    
    /*
    ** This is where I am stuck; how would I use the elements
    ** of factorialTable to initialize a static array?
    */
    

Solution

  • http://www.boost.org/doc/libs/1_46_0/libs/preprocessor/doc/index.html

    #define MACRO(z, i, data) \
        mpl::at_c<data,i>::value
    
    static const data[] = { BOOST_PP_ENUM(N, MACRO, factorialTable) };