• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 implements over 2200 functions for 1-dimensional arithmetic
15 #  * array manipulation in C.  The idea is to use preprocessor data structures,
16 #  * lists, and tuples for storing metainformation to be used for generating
17 #  * the actual C code.
18 #  *
19 #  * Who needs templates anyway? :)
20 #  *
21 #  * Compile with any C compiler with a standards conforming preprocessor.
22 #  */
23 #
24 # include <boost/preprocessor/comparison/less.hpp>
25 # include <boost/preprocessor/control/if.hpp>
26 # include <boost/preprocessor/list/at.hpp>
27 # include <boost/preprocessor/list/cat.hpp>
28 # include <boost/preprocessor/list/for_each_product.hpp>
29 # include <boost/preprocessor/logical/or.hpp>
30 # include <boost/preprocessor/tuple/to_list.hpp>
31 # include <boost/preprocessor/tuple/eat.hpp>
32 #
33 # /* Information about C operators */
34 #
35 # /* Accessors for the operator datatype. */
36 # define OP_SYMBOL(O)      BOOST_PP_TUPLE_ELEM(5, 0, O)
37 # define OP_NAME(O)        BOOST_PP_TUPLE_ELEM(5, 1, O)
38 # define OP_IS_FLOATING(O) BOOST_PP_TUPLE_ELEM(5, 2, O)
39 # define OP_IS_LOGICAL(O)  BOOST_PP_TUPLE_ELEM(5, 3, O)
40 # define OP_IS_SHIFT(O)    BOOST_PP_TUPLE_ELEM(5, 4, O)
41 #
42 # /* List of applicative unary operators. */
43 # define APPLICATIVE_UNARY_OPS \
44    BOOST_PP_TUPLE_TO_LIST( \
45       3, \
46       ( \
47          ( ! , logical_not, 1, 1, 0), \
48          ( ~ , bitwise_not, 0, 0, 0), \
49          ( - , neg,         1, 0, 0) \
50       ) \
51    ) \
52    /**/
53 #
54 # /* List of applicative binary operators. */
55 # define APPLICATIVE_BINARY_OPS \
56    BOOST_PP_TUPLE_TO_LIST( \
57       18, \
58       ( \
59          ( *  , mul           ,1 ,0 ,0), \
60          ( /  , div           ,1 ,0 ,0), \
61          ( %  , mod           ,0 ,0 ,0), \
62          ( +  , add           ,1 ,0 ,0), \
63          ( -  , sub           ,1 ,0 ,0), \
64          ( << , shift_left    ,0 ,0 ,1), \
65          ( >> , shift_right   ,0 ,0 ,1), \
66          ( <  , less          ,1 ,1 ,0), \
67          ( <= , less_equal    ,1 ,1 ,0), \
68          ( >= , greater_equal ,1 ,1 ,0), \
69          ( >  , greater       ,1 ,1 ,0), \
70          ( == , equal         ,1 ,1 ,0), \
71          ( != , not_equal     ,1 ,1 ,0), \
72          ( &  , bitwise_and   ,0 ,0 ,0), \
73          ( |  , bitwise_or    ,0 ,0 ,0), \
74          ( ^  , bitwise_xor   ,0 ,0 ,0), \
75          ( && , logical_and   ,1 ,1 ,0), \
76          ( || , logical_or    ,1 ,1 ,0) \
77       ) \
78    ) \
79    /**/
80 #
81 # /* Information about C built-in types. */
82 #
83 # /* Accessors for the type datatype. */
84 # define TYPE_NAME(T)         BOOST_PP_TUPLE_ELEM(4, 0, T)
85 # define TYPE_ABBREVIATION(T) BOOST_PP_TUPLE_ELEM(4, 1, T)
86 # define TYPE_IS_FLOATING(T)  BOOST_PP_TUPLE_ELEM(4, 2, T)
87 # define TYPE_RANK(T)         BOOST_PP_TUPLE_ELEM(4, 3, T)
88 #
89 # /* List of C built-in types. */
90 # define BUILTIN_TYPES \
91    BOOST_PP_TUPLE_TO_LIST( \
92       12, \
93       ( \
94          ( signed char    ,sc, 0, 1), \
95          ( char           ,ch, 0, 1), \
96          ( unsigned char  ,uc, 0, 1), \
97          ( short          ,ss, 0, 2), \
98          ( unsigned short ,us, 0, 2), \
99          TYPE_INT, \
100          ( unsigned       ,ui, 0, 4), \
101          ( long           ,sl, 0, 5), \
102          ( unsigned long  ,ul, 0, 6), \
103          ( float          ,fl, 1, 7), \
104          ( double         ,db, 1, 8), \
105          ( long double    ,ld, 1, 9) \
106       ) \
107    ) \
108    /**/
109 #
110 # /* Type int is needed in some type computations. */
111 # define TYPE_INT (int, si, 0, 3)
112 #
113 # /* Type computation macros. */
114 # define TYPE_OF_INTEGER_PROMOTION(T) \
115    BOOST_PP_IF( \
116       BOOST_PP_LESS(TYPE_RANK(T), TYPE_RANK(TYPE_INT)), \
117       TYPE_INT, T \
118    ) \
119    /**/
120 # define TYPE_OF_USUAL_ARITHMETIC_CONVERSION(L, R) \
121    TYPE_OF_INTEGER_PROMOTION( \
122       BOOST_PP_IF( \
123          BOOST_PP_LESS(TYPE_RANK(L), TYPE_RANK(R)), \
124          R, L \
125       ) \
126    ) \
127    /**/
128 # define TYPE_OF_UNARY_OP(O, T) \
129    BOOST_PP_IF( \
130       OP_IS_LOGICAL(O), \
131       TYPE_INT, TYPE_OF_INTEGER_PROMOTION(T) \
132    ) \
133    /**/
134 # define TYPE_OF_BINARY_OP(O, L, R) \
135    BOOST_PP_IF( \
136       OP_IS_LOGICAL(O), TYPE_INT, \
137       BOOST_PP_IF( \
138          OP_IS_SHIFT(O), \
139          TYPE_OF_INTEGER_PROMOTION(L), \
140          TYPE_OF_USUAL_ARITHMETIC_CONVERSION(L,R) \
141       ) \
142    ) \
143    /**/
144 # define IS_VALID_UNARY_OP_AND_TYPE_COMBINATION(O, T) \
145    BOOST_PP_IF( \
146       TYPE_IS_FLOATING(T), \
147       OP_IS_FLOATING(O), 1 \
148    ) \
149    /**/
150 # define IS_VALID_BINARY_OP_AND_TYPE_COMBINATION(O, L, R) \
151    BOOST_PP_IF( \
152       BOOST_PP_OR(TYPE_IS_FLOATING(L), TYPE_IS_FLOATING(R)), \
153       OP_IS_FLOATING(O), 1 \
154    ) \
155    /**/
156 #
157 # /* Generates code for all unary operators and integral types. */
158 # define UNARY_ARRAY_OP(_, OT) \
159    BOOST_PP_IF( \
160       IS_VALID_UNARY_OP_AND_TYPE_COMBINATION OT, \
161       UNARY_ARRAY_OP_CODE, BOOST_PP_TUPLE_EAT(2) \
162    ) OT \
163    /**/
164 # define UNARY_ARRAY_OP_CODE(O, T) \
165    void BOOST_PP_LIST_CAT(BOOST_PP_TUPLE_TO_LIST(4, (array_, OP_NAME(O), _, TYPE_ABBREVIATION(T)))) \
166    (const TYPE_NAME(T)* in, TYPE_NAME(TYPE_OF_UNARY_OP(O, T))* out, unsigned n) { \
167       do { \
168          *out++ = OP_SYMBOL(O) *in++; \
169       } while (--n); \
170    } \
171    /**/
172 
173 BOOST_PP_LIST_FOR_EACH_PRODUCT(UNARY_ARRAY_OP, 2, (APPLICATIVE_UNARY_OPS, BUILTIN_TYPES))
174 
175 # /* Generates code for all binary operators and integral type pairs. */
176 # define BINARY_ARRAY_OP(_, OLR) \
177    BOOST_PP_IF( \
178       IS_VALID_BINARY_OP_AND_TYPE_COMBINATION OLR, \
179       BINARY_ARRAY_OP_CODE, BOOST_PP_TUPLE_EAT(3) \
180    ) OLR \
181    /**/
182 # define BINARY_ARRAY_OP_CODE(O, L, R) \
183    void BOOST_PP_LIST_CAT( \
184       BOOST_PP_TUPLE_TO_LIST( \
185          6, (array_, OP_NAME(O), _, TYPE_ABBREVIATION(L), _, TYPE_ABBREVIATION(R)) \
186       ) \
187    )(const TYPE_NAME(L)* lhs_in, const TYPE_NAME(R)* rhs_in, TYPE_NAME(TYPE_OF_BINARY_OP(O, L, R))* out, unsigned n) { \
188       do { \
189          *out++ = *lhs_in OP_SYMBOL(O) *rhs_in; \
190          ++lhs_in; \
191          ++rhs_in; \
192       } while (--n); \
193    } \
194    /**/
195 
196 BOOST_PP_LIST_FOR_EACH_PRODUCT(BINARY_ARRAY_OP, 3, (APPLICATIVE_BINARY_OPS, BUILTIN_TYPES, BUILTIN_TYPES))
197