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