197 lines
6.1 KiB
C
197 lines
6.1 KiB
C
# /* Copyright (C) 2002
|
|
# * Housemarque Oy
|
|
# * http://www.housemarque.com
|
|
# *
|
|
# * Distributed under the Boost Software License, Version 1.0. (See
|
|
# * accompanying file LICENSE_1_0.txt or copy at
|
|
# * http://www.boost.org/LICENSE_1_0.txt)
|
|
# */
|
|
#
|
|
# /* Revised by Paul Mensonides (2002) */
|
|
#
|
|
# /* See http://www.boost.org for most recent version. */
|
|
#
|
|
# /* This example implements over 2200 functions for 1-dimensional arithmetic
|
|
# * array manipulation in C. The idea is to use preprocessor data structures,
|
|
# * lists, and tuples for storing metainformation to be used for generating
|
|
# * the actual C code.
|
|
# *
|
|
# * Who needs templates anyway? :)
|
|
# *
|
|
# * Compile with any C compiler with a standards conforming preprocessor.
|
|
# */
|
|
#
|
|
# include <boost/preprocessor/comparison/less.hpp>
|
|
# include <boost/preprocessor/control/if.hpp>
|
|
# include <boost/preprocessor/list/at.hpp>
|
|
# include <boost/preprocessor/list/cat.hpp>
|
|
# include <boost/preprocessor/list/for_each_product.hpp>
|
|
# include <boost/preprocessor/logical/or.hpp>
|
|
# include <boost/preprocessor/tuple/to_list.hpp>
|
|
# include <boost/preprocessor/tuple/eat.hpp>
|
|
#
|
|
# /* Information about C operators */
|
|
#
|
|
# /* Accessors for the operator datatype. */
|
|
# define OP_SYMBOL(O) BOOST_PP_TUPLE_ELEM(5, 0, O)
|
|
# define OP_NAME(O) BOOST_PP_TUPLE_ELEM(5, 1, O)
|
|
# define OP_IS_FLOATING(O) BOOST_PP_TUPLE_ELEM(5, 2, O)
|
|
# define OP_IS_LOGICAL(O) BOOST_PP_TUPLE_ELEM(5, 3, O)
|
|
# define OP_IS_SHIFT(O) BOOST_PP_TUPLE_ELEM(5, 4, O)
|
|
#
|
|
# /* List of applicative unary operators. */
|
|
# define APPLICATIVE_UNARY_OPS \
|
|
BOOST_PP_TUPLE_TO_LIST( \
|
|
3, \
|
|
( \
|
|
( ! , logical_not, 1, 1, 0), \
|
|
( ~ , bitwise_not, 0, 0, 0), \
|
|
( - , neg, 1, 0, 0) \
|
|
) \
|
|
) \
|
|
/**/
|
|
#
|
|
# /* List of applicative binary operators. */
|
|
# define APPLICATIVE_BINARY_OPS \
|
|
BOOST_PP_TUPLE_TO_LIST( \
|
|
18, \
|
|
( \
|
|
( * , mul ,1 ,0 ,0), \
|
|
( / , div ,1 ,0 ,0), \
|
|
( % , mod ,0 ,0 ,0), \
|
|
( + , add ,1 ,0 ,0), \
|
|
( - , sub ,1 ,0 ,0), \
|
|
( << , shift_left ,0 ,0 ,1), \
|
|
( >> , shift_right ,0 ,0 ,1), \
|
|
( < , less ,1 ,1 ,0), \
|
|
( <= , less_equal ,1 ,1 ,0), \
|
|
( >= , greater_equal ,1 ,1 ,0), \
|
|
( > , greater ,1 ,1 ,0), \
|
|
( == , equal ,1 ,1 ,0), \
|
|
( != , not_equal ,1 ,1 ,0), \
|
|
( & , bitwise_and ,0 ,0 ,0), \
|
|
( | , bitwise_or ,0 ,0 ,0), \
|
|
( ^ , bitwise_xor ,0 ,0 ,0), \
|
|
( && , logical_and ,1 ,1 ,0), \
|
|
( || , logical_or ,1 ,1 ,0) \
|
|
) \
|
|
) \
|
|
/**/
|
|
#
|
|
# /* Information about C built-in types. */
|
|
#
|
|
# /* Accessors for the type datatype. */
|
|
# define TYPE_NAME(T) BOOST_PP_TUPLE_ELEM(4, 0, T)
|
|
# define TYPE_ABBREVIATION(T) BOOST_PP_TUPLE_ELEM(4, 1, T)
|
|
# define TYPE_IS_FLOATING(T) BOOST_PP_TUPLE_ELEM(4, 2, T)
|
|
# define TYPE_RANK(T) BOOST_PP_TUPLE_ELEM(4, 3, T)
|
|
#
|
|
# /* List of C built-in types. */
|
|
# define BUILTIN_TYPES \
|
|
BOOST_PP_TUPLE_TO_LIST( \
|
|
12, \
|
|
( \
|
|
( signed char ,sc, 0, 1), \
|
|
( char ,ch, 0, 1), \
|
|
( unsigned char ,uc, 0, 1), \
|
|
( short ,ss, 0, 2), \
|
|
( unsigned short ,us, 0, 2), \
|
|
TYPE_INT, \
|
|
( unsigned ,ui, 0, 4), \
|
|
( long ,sl, 0, 5), \
|
|
( unsigned long ,ul, 0, 6), \
|
|
( float ,fl, 1, 7), \
|
|
( double ,db, 1, 8), \
|
|
( long double ,ld, 1, 9) \
|
|
) \
|
|
) \
|
|
/**/
|
|
#
|
|
# /* Type int is needed in some type computations. */
|
|
# define TYPE_INT (int, si, 0, 3)
|
|
#
|
|
# /* Type computation macros. */
|
|
# define TYPE_OF_INTEGER_PROMOTION(T) \
|
|
BOOST_PP_IF( \
|
|
BOOST_PP_LESS(TYPE_RANK(T), TYPE_RANK(TYPE_INT)), \
|
|
TYPE_INT, T \
|
|
) \
|
|
/**/
|
|
# define TYPE_OF_USUAL_ARITHMETIC_CONVERSION(L, R) \
|
|
TYPE_OF_INTEGER_PROMOTION( \
|
|
BOOST_PP_IF( \
|
|
BOOST_PP_LESS(TYPE_RANK(L), TYPE_RANK(R)), \
|
|
R, L \
|
|
) \
|
|
) \
|
|
/**/
|
|
# define TYPE_OF_UNARY_OP(O, T) \
|
|
BOOST_PP_IF( \
|
|
OP_IS_LOGICAL(O), \
|
|
TYPE_INT, TYPE_OF_INTEGER_PROMOTION(T) \
|
|
) \
|
|
/**/
|
|
# define TYPE_OF_BINARY_OP(O, L, R) \
|
|
BOOST_PP_IF( \
|
|
OP_IS_LOGICAL(O), TYPE_INT, \
|
|
BOOST_PP_IF( \
|
|
OP_IS_SHIFT(O), \
|
|
TYPE_OF_INTEGER_PROMOTION(L), \
|
|
TYPE_OF_USUAL_ARITHMETIC_CONVERSION(L,R) \
|
|
) \
|
|
) \
|
|
/**/
|
|
# define IS_VALID_UNARY_OP_AND_TYPE_COMBINATION(O, T) \
|
|
BOOST_PP_IF( \
|
|
TYPE_IS_FLOATING(T), \
|
|
OP_IS_FLOATING(O), 1 \
|
|
) \
|
|
/**/
|
|
# define IS_VALID_BINARY_OP_AND_TYPE_COMBINATION(O, L, R) \
|
|
BOOST_PP_IF( \
|
|
BOOST_PP_OR(TYPE_IS_FLOATING(L), TYPE_IS_FLOATING(R)), \
|
|
OP_IS_FLOATING(O), 1 \
|
|
) \
|
|
/**/
|
|
#
|
|
# /* Generates code for all unary operators and integral types. */
|
|
# define UNARY_ARRAY_OP(_, OT) \
|
|
BOOST_PP_IF( \
|
|
IS_VALID_UNARY_OP_AND_TYPE_COMBINATION OT, \
|
|
UNARY_ARRAY_OP_CODE, BOOST_PP_TUPLE_EAT(2) \
|
|
) OT \
|
|
/**/
|
|
# define UNARY_ARRAY_OP_CODE(O, T) \
|
|
void BOOST_PP_LIST_CAT(BOOST_PP_TUPLE_TO_LIST(4, (array_, OP_NAME(O), _, TYPE_ABBREVIATION(T)))) \
|
|
(const TYPE_NAME(T)* in, TYPE_NAME(TYPE_OF_UNARY_OP(O, T))* out, unsigned n) { \
|
|
do { \
|
|
*out++ = OP_SYMBOL(O) *in++; \
|
|
} while (--n); \
|
|
} \
|
|
/**/
|
|
|
|
BOOST_PP_LIST_FOR_EACH_PRODUCT(UNARY_ARRAY_OP, 2, (APPLICATIVE_UNARY_OPS, BUILTIN_TYPES))
|
|
|
|
# /* Generates code for all binary operators and integral type pairs. */
|
|
# define BINARY_ARRAY_OP(_, OLR) \
|
|
BOOST_PP_IF( \
|
|
IS_VALID_BINARY_OP_AND_TYPE_COMBINATION OLR, \
|
|
BINARY_ARRAY_OP_CODE, BOOST_PP_TUPLE_EAT(3) \
|
|
) OLR \
|
|
/**/
|
|
# define BINARY_ARRAY_OP_CODE(O, L, R) \
|
|
void BOOST_PP_LIST_CAT( \
|
|
BOOST_PP_TUPLE_TO_LIST( \
|
|
6, (array_, OP_NAME(O), _, TYPE_ABBREVIATION(L), _, TYPE_ABBREVIATION(R)) \
|
|
) \
|
|
)(const TYPE_NAME(L)* lhs_in, const TYPE_NAME(R)* rhs_in, TYPE_NAME(TYPE_OF_BINARY_OP(O, L, R))* out, unsigned n) { \
|
|
do { \
|
|
*out++ = *lhs_in OP_SYMBOL(O) *rhs_in; \
|
|
++lhs_in; \
|
|
++rhs_in; \
|
|
} while (--n); \
|
|
} \
|
|
/**/
|
|
|
|
BOOST_PP_LIST_FOR_EACH_PRODUCT(BINARY_ARRAY_OP, 3, (APPLICATIVE_BINARY_OPS, BUILTIN_TYPES, BUILTIN_TYPES))
|