diff --git a/example/array_arithmetic.c b/example/array_arithmetic.c index 8fb8ec8..7b7751a 100644 --- a/example/array_arithmetic.c +++ b/example/array_arithmetic.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -31,35 +32,9 @@ #include #include - /*sym , name ,bin,flt,log,sh?,com*/ -#define UNARY_OPS\ - (( ! , logical_not , 0 , 1 , 1 , 0 , 0 ),\ - (( ~ , bitwise_not , 0 , 0 , 0 , 0 , 0 ),\ - (( - , neg , 0 , 1 , 0 , 0 , 0 ),\ - (_,_,0),1),1),1) - - /*sym , name ,bin,flt,log,sh?,com*/ -#define BINARY_OPS\ - (( * , mul , 1 , 1 , 0 , 0 , 1 ),\ - (( / , div , 1 , 1 , 0 , 0 , 0 ),\ - (( % , mod , 1 , 0 , 0 , 0 , 0 ),\ - (( + , add , 1 , 1 , 0 , 0 , 1 ),\ - (( - , sub , 1 , 1 , 0 , 0 , 0 ),\ - (( << , shift_left , 1 , 0 , 0 , 1 , 0 ),\ - (( >> , shift_right , 1 , 0 , 0 , 1 , 0 ),\ - (( < , less , 1 , 1 , 1 , 0 , 0 ),\ - (( <= , less_equal , 1 , 1 , 1 , 0 , 0 ),\ - (( >= , greater_equal , 1 , 1 , 1 , 0 , 0 ),\ - (( > , greater , 1 , 1 , 1 , 0 , 0 ),\ - (( == , equal , 1 , 1 , 1 , 0 , 1 ),\ - (( != , not_equal , 1 , 1 , 1 , 0 , 1 ),\ - (( & , bitwise_and , 1 , 0 , 0 , 0 , 1 ),\ - (( | , bitwise_or , 1 , 0 , 0 , 0 , 1 ),\ - (( ^ , bitwise_xor , 1 , 0 , 0 , 0 , 1 ),\ - (( && , logical_and , 1 , 1 , 1 , 0 , 1 ),\ - (( || , logical_or , 1 , 1 , 1 , 0 , 1 ),\ - (_,_,0),1),1),1),1),1),1),1),1),1),1),1),1),1),1),1),1),1),1) +/* ** Information about C operators for preprocessor metaprogramming. ** */ +/* Accessors for the operator datatype. */ #define OP_SYMBOL(O) BOOST_PP_TUPLE7_ELEM0 O #define OP_NAME(O) BOOST_PP_TUPLE7_ELEM1 O #define OP_IS_BINARY(O) BOOST_PP_TUPLE7_ELEM2 O @@ -68,29 +43,87 @@ #define OP_IS_SHIFT(O) BOOST_PP_TUPLE7_ELEM5 O #define OP_IS_COMMUTATIVE(O) BOOST_PP_TUPLE7_ELEM6 O - /* type ,abbr,flt,lng,uns,siz*/ -#define TYPES\ - (( signed char , sc , 0 , 0 , 0 , 1 ),\ - (( unsigned char , uc , 0 , 0 , 1 , 1 ),\ - (( short , ss , 0 , 0 , 0 , 2 ),\ - (( unsigned short , us , 0 , 0 , 1 , 2 ),\ - (TYPE_INT,\ - (( unsigned int , ui , 0 , 0 , 1 , 4 ),\ - (( long , sl , 0 , 1 , 0 , 4 ),\ - (( unsigned long , ul , 0 , 1 , 1 , 4 ),\ - (( float , fl , 1 , 0 , 0 , 4 ),\ - (( double , db , 1 , 0 , 0 , 8 ),\ - (( long double , ld , 1 , 1 , 0 , 8 ),\ - (_,_,0),1),1),1),1),1),1),1),1),1),1),1) +/* List of applicative unary operators. */ +#define APPLICATIVE_UNARY_OPS\ + BOOST_PP_TUPLE_TO_LIST\ + ( 3\ + , ( ( ! , logical_not , 0 , 1 , 1 , 0 , 0 )\ + , ( ~ , bitwise_not , 0 , 0 , 0 , 0 , 0 )\ + , ( - , neg , 0 , 1 , 0 , 0 , 0 )\ + )\ + ) -#define TYPE_INT ( int , si , 0 , 0 , 0 , 4 ) +/* List of applicative binary operators. */ +#define APPLICATIVE_BINARY_OPS\ + BOOST_PP_LIST_APPEND\ + ( BOOST_PP_TUPLE_TO_LIST(\ + ( 2\ + , ( ( * , mul , 1 , 1 , 0 , 0 , 1 )\ + , ( / , div , 1 , 1 , 0 , 0 , 0 )\ + )\ + ),\ + , BOOST_PP_TUPLE_TO_LIST\ + ( 16\ + , ( ( % , mod , 1 , 0 , 0 , 0 , 0 )\ + , ( + , add , 1 , 1 , 0 , 0 , 1 )\ + , ( - , sub , 1 , 1 , 0 , 0 , 0 )\ + , ( << , shift_left , 1 , 0 , 0 , 1 , 0 )\ + , ( >> , shift_right , 1 , 0 , 0 , 1 , 0 )\ + , ( < , less , 1 , 1 , 1 , 0 , 0 )\ + , ( <= , less_equal , 1 , 1 , 1 , 0 , 0 )\ + , ( >= , greater_equal , 1 , 1 , 1 , 0 , 0 )\ + , ( > , greater , 1 , 1 , 1 , 0 , 0 )\ + , ( == , equal , 1 , 1 , 1 , 0 , 1 )\ + , ( != , not_equal , 1 , 1 , 1 , 0 , 1 )\ + , ( & , bitwise_and , 1 , 0 , 0 , 0 , 1 )\ + , ( | , bitwise_or , 1 , 0 , 0 , 0 , 1 )\ + , ( ^ , bitwise_xor , 1 , 0 , 0 , 0 , 1 )\ + , ( && , logical_and , 1 , 1 , 1 , 0 , 1 )\ + , ( || , logical_or , 1 , 1 , 1 , 0 , 1 )\ + )\ + )\ + ) +/* ** Information about C built-in types for preprocessor metaprogramming. ** */ + +/* Accessors for the type datatype. */ #define TYPE_NAME(T) BOOST_PP_TUPLE6_ELEM0 T #define TYPE_ABBREVIATION(T) BOOST_PP_TUPLE6_ELEM1 T #define TYPE_IS_FLOATING(T) BOOST_PP_TUPLE6_ELEM2 T #define TYPE_IS_LONG(T) BOOST_PP_TUPLE6_ELEM3 T #define TYPE_IS_UNSIGNED(T) BOOST_PP_TUPLE6_ELEM4 T #define TYPE_SIZE(T) BOOST_PP_TUPLE6_ELEM5 T + +/* List of C built-in types. + * + * Some of the information is platform dependent, but this example + * does not take that into consideration. + */ +#define BUILTIN_TYPES\ + BOOST_PP_TUPLE_TO_LIST\ + ( 12\ + , ( ( signed char , sc , 0 , 0 , 0 , 1 )\ + , ( char , ch , 0 , 0 , 0 , 1 )\ + , ( unsigned char , uc , 0 , 0 , 1 , 1 )\ + , ( short , ss , 0 , 0 , 0 , 2 )\ + , ( unsigned short , us , 0 , 0 , 1 , 2 )\ + , TYPE_INT\ + , ( unsigned int , ui , 0 , 0 , 1 , 4 )\ + , ( long , sl , 0 , 1 , 0 , 4 )\ + , ( unsigned long , ul , 0 , 1 , 1 , 4 )\ + , ( float , fl , 1 , 0 , 0 , 4 )\ + , ( double , db , 1 , 0 , 0 , 8 )\ + , ( long double , ld , 1 , 1 , 0 , 8 )\ + )\ + ) + +/* Type int is needed in some type operations. */ +#define TYPE_INT ( int , si , 0 , 0 , 0 , 4 ) + +/* Computes the rank of the type for: + * - integer promotions, and + * - usual arithmetic conversions. + */ #define TYPE_RANK(T)\ BOOST_PP_ADD\ ( BOOST_PP_ADD\ @@ -102,15 +135,22 @@ )\ , TYPE_IS_UNSIGNED(T)\ ) + #define TYPE_IS_SAME(L,R) BOOST_PP_EQUAL(TYPE_RANK(L),TYPE_RANK(R)) -/* Integer promotion and usual arithmetic conversions */ -#define INTEGER_PROMOTION(T) BOOST_PP_IF(BOOST_PP_LESS(TYPE_RANK(T),TYPE_RANK(TYPE_INT)),TYPE_INT,T) +/* Compute the type of the result of an integral promotion. */ +#define INTEGER_PROMOTION(T) BOOST_PP_IF(BOOST_PP_LESS(TYPE_RANK(T),TYPE_RANK(TYPE_INT)),TYPE_INT,T) + +/* Computes the type of the result of an usual arithmetic conversion. */ #define USUAL_ARITHMETIC_CONVERSION(L,R) INTEGER_PROMOTION(BOOST_PP_IF(BOOST_PP_LESS(TYPE_RANK(L),TYPE_RANK(R)),R,L)) -#define UNARY_OP_RESULT(O,T) BOOST_PP_IF(OP_IS_LOGICAL(O),TYPE_INT,INTEGER_PROMOTION(T)) +/* Computes the type of applying a unary operator. */ +#define UNARY_OP_RESULT(O,T) BOOST_PP_IF(OP_IS_LOGICAL(O),TYPE_INT,INTEGER_PROMOTION(T)) + +/* Computes the type of applying a binary operator. */ #define BINARY_OP_RESULT(O,L,R) BOOST_PP_IF(OP_IS_LOGICAL(O),TYPE_INT,BOOST_PP_IF(OP_IS_SHIFT(O),INTEGER_PROMOTION(L),USUAL_ARITHMETIC_CONVERSION(L,R))) +/* Generates code for all all unary operators and integral types. */ #define UNARY_ARRAY_OP(_,L)\ UNARY_ARRAY_OP2(BOOST_PP_LIST_AT(L,1),BOOST_PP_LIST_AT(L,0)) #define UNARY_ARRAY_OP2(O,T)\ @@ -124,9 +164,9 @@ (const TYPE_NAME(T)* in, TYPE_NAME(UNARY_OP_RESULT(O,T))* out, size_t n)\ { do { *out++ = OP_SYMBOL(O) *in++; } while (--n); } -/* Unary array ops */ -BOOST_PP_LIST_FOR_EACH_PRODUCT(UNARY_ARRAY_OP,_,BOOST_PP_TUPLE_TO_LIST(2,(UNARY_OPS,TYPES))) +BOOST_PP_LIST_FOR_EACH_PRODUCT(UNARY_ARRAY_OP,_,BOOST_PP_TUPLE_TO_LIST(2,(APPLICATIVE_UNARY_OPS,TYPES))) +/* Generates code for all binary operators and integral type pairs. */ #define BINARY_ARRAY_OP(_,L)\ BINARY_ARRAY_OP2(BOOST_PP_LIST_AT(L,2),BOOST_PP_LIST_AT(L,1),BOOST_PP_LIST_AT(L,0)) #define BINARY_ARRAY_OP2(O,L,R)\ @@ -140,5 +180,4 @@ BOOST_PP_LIST_FOR_EACH_PRODUCT(UNARY_ARRAY_OP,_,BOOST_PP_TUPLE_TO_LIST(2,(UNARY_ (const TYPE_NAME(L)* lhs_in, const TYPE_NAME(R)* rhs_in, TYPE_NAME(BINARY_OP_RESULT(O,L,R))* out, size_t n)\ { do { *out++ = *lhs_in++ OP_SYMBOL(O) *rhs_in++; } while (--n); } -/* Binary array ops */ -BOOST_PP_LIST_FOR_EACH_PRODUCT(BINARY_ARRAY_OP,_,BOOST_PP_TUPLE_TO_LIST(3,(BINARY_OPS,TYPES,TYPES))) +BOOST_PP_LIST_FOR_EACH_PRODUCT(BINARY_ARRAY_OP,_,BOOST_PP_TUPLE_TO_LIST(3,(APPLICATIVE_BINARY_OPS,TYPES,TYPES)))