Boost.PPでエラトステネスの篩

プリプロセッサをやればかわいい妹ができると聞いて。

#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/arithmetic/mod.hpp>
#include <boost/preprocessor/comparison/not_equal.hpp>
#include <boost/preprocessor/repetition/for.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/filter.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/tuple/elem.hpp>

// The RANGE macro generates a seq containing arithmetic progressions.
// For example, RANGE(5, 10) expands to: (5) (6) (7) (8) (9)

#define RANGE_PRED(r, state) \
    BOOST_PP_NOT_EQUAL(\
        BOOST_PP_TUPLE_ELEM(2, 0, state),\
        BOOST_PP_TUPLE_ELEM(2, 1, state)\
    )

#define RANGE_OP(r, state) \
    (\
        BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 0, state)),\
        BOOST_PP_TUPLE_ELEM(2, 1, state)\
    )

#define RANGE_MACRO(r, state)\
    (BOOST_PP_TUPLE_ELEM(2, 0, state))

#define RANGE(first, last) \
    BOOST_PP_FOR((first, last), RANGE_PRED, RANGE_OP, RANGE_MACRO)

// The SIEVE macro represents the Sieve of Eratosthenes.

#define SIEVE_PRED(r, state) \
    BOOST_PP_NOT_EQUAL(BOOST_PP_SEQ_HEAD(state), 1)

#define SIEVE_OP_PRED(s, data, elem) \
    BOOST_PP_MOD(elem, data)

#define SIEVE_OP(r, state) \
    BOOST_PP_SEQ_FILTER(\
        SIEVE_OP_PRED,\
        BOOST_PP_SEQ_HEAD(state),\
        BOOST_PP_SEQ_TAIL(state)\
    )

#define SIEVE_MACRO(r, state) \
    (BOOST_PP_SEQ_HEAD(state))

#define SIEVE(seq) \
    BOOST_PP_FOR(seq(1), SIEVE_PRED, SIEVE_OP, SIEVE_MACRO)

// The PRIMES macro generates a comma-separated list of prime numbers.
// For example, PRIMES(10) expands to: 2, 3, 5, 7

#define PRIMES(max) \
    BOOST_PP_SEQ_ENUM(SIEVE(RANGE(2, max)))


#include <iostream>

int main()
{
    int primes[] = { PRIMES(100) };
    for (int i = 0; i < sizeof(primes) / sizeof(int); ++i)
        std::cout << primes[i] << ' ';
}

出力

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97