1 # /* Copyright (C) 2002
2 #  * Housemarque Oy
3 #  * http://www.housemarque.com
4 #  *
5 #  * Distributed under the Boost Software License, Version 1.0. (See
6 #  * accompanying file LICENSE_1_0.txt or copy at
7 #  * http://www.boost.org/LICENSE_1_0.txt)
8 #  */
9 #
10 # /* Revised by Paul Mensonides (2002) */
11 #
12 # /* See http://www.boost.org for most recent version. */
13 #
14 # /* This example uses the preprocessor library to implement a generalized
15 #  * macro for implementing Duff's Device.
16 #  *
17 #  * This example was inspired by an original generalized macro for
18 #  * for implementing Duff's Device written by Joerg Walter.
19 #  */
20 #
21 # include <assert.h>
22 #
23 # include <boost/preprocessor/repetition/repeat.hpp>
24 # include <boost/preprocessor/tuple/elem.hpp>
25 #
26 # /* Expands to a Duff's Device. */
27 # define DUFFS_DEVICE(UNROLLING_FACTOR, COUNTER_TYPE, N, STATEMENT) \
28    do { \
29       COUNTER_TYPE duffs_device_initial_cnt = (N); \
30       if (duffs_device_initial_cnt > 0) { \
31          COUNTER_TYPE duffs_device_running_cnt = (duffs_device_initial_cnt + (UNROLLING_FACTOR - 1)) / UNROLLING_FACTOR; \
32          switch (duffs_device_initial_cnt % UNROLLING_FACTOR) { \
33             do { \
34                BOOST_PP_REPEAT(UNROLLING_FACTOR, DUFFS_DEVICE_C, (UNROLLING_FACTOR, { STATEMENT })) \
35             } while (--duffs_device_running_cnt); \
36          } \
37       } \
38    } while (0) \
39    /**/
40 #
41 # define DUFFS_DEVICE_C(Z, I, UNROLLING_FACTOR_STATEMENT) \
42    case (I ? BOOST_PP_TUPLE_ELEM(2, 0, UNROLLING_FACTOR_STATEMENT) - I : 0): \
43       BOOST_PP_TUPLE_ELEM(2, 1, UNROLLING_FACTOR_STATEMENT); \
44    /**/
45 #
46 # ifndef UNROLLING_FACTOR
47 # define UNROLLING_FACTOR 16
48 # endif
49 #
50 # ifndef N
51 # define N 1000
52 # endif
53 
main(void)54 int main(void) {
55    int i = 0;
56    DUFFS_DEVICE(UNROLLING_FACTOR, int, 0, ++i;);
57    assert(i == 0);
58    DUFFS_DEVICE(UNROLLING_FACTOR, int, N, ++i;);
59    assert(i == N);
60    return 0;
61 }
62