diff --git a/example/array_arithmetic.c b/example/array_arithmetic.c index 91d85ac..a6437fc 100644 --- a/example/array_arithmetic.c +++ b/example/array_arithmetic.c @@ -24,32 +24,25 @@ #include #include #include -#include -#include #include -#include -#include -#include #include -/* ** Information about C operators for preprocessor metaprogramming. ** */ +/* Information about C operators. */ /* 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 -#define OP_IS_FLOATING(O) BOOST_PP_TUPLE7_ELEM3 O -#define OP_IS_LOGICAL(O) BOOST_PP_TUPLE7_ELEM4 O -#define OP_IS_SHIFT(O) BOOST_PP_TUPLE7_ELEM5 O -#define OP_IS_COMMUTATIVE(O) BOOST_PP_TUPLE7_ELEM6 O +#define OP_SYMBOL(O) BOOST_PP_TUPLE5_ELEM0 O +#define OP_NAME(O) BOOST_PP_TUPLE5_ELEM1 O +#define OP_IS_FLOATING(O) BOOST_PP_TUPLE5_ELEM2 O +#define OP_IS_LOGICAL(O) BOOST_PP_TUPLE5_ELEM3 O +#define OP_IS_SHIFT(O) BOOST_PP_TUPLE5_ELEM4 O /* 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 )\ + , ( ( ! , logical_not , 1 , 1 , 0 )\ + , ( ~ , bitwise_not , 0 , 0 , 0 )\ + , ( - , neg , 1 , 0 , 0 )\ )\ ) @@ -58,107 +51,86 @@ BOOST_PP_LIST_APPEND\ ( BOOST_PP_TUPLE_TO_LIST\ ( 2\ - , ( ( * , mul , 1 , 1 , 0 , 0 , 1 )\ - , ( / , div , 1 , 1 , 0 , 0 , 0 )\ + , ( ( * , mul , 1 , 0 , 0 )\ + , ( / , div , 1 , 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 )\ + , ( ( % , 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 for preprocessor metaprogramming. ** */ +/* Information about C built-in types. */ /* Accessors for the type datatype. */ -#define TYPE_NAME(T) BOOST_PP_TUPLE5_ELEM0 T -#define TYPE_ABBREVIATION(T) BOOST_PP_TUPLE5_ELEM1 T -#define TYPE_IS_FLOATING(T) BOOST_PP_TUPLE5_ELEM2 T -#define TYPE_IS_UNSIGNED(T) BOOST_PP_TUPLE5_ELEM3 T -#define TYPE_RANK(T) BOOST_PP_TUPLE5_ELEM4 T +#define TYPE_NAME(T) BOOST_PP_TUPLE4_ELEM0 T +#define TYPE_ABBREVIATION(T) BOOST_PP_TUPLE4_ELEM1 T +#define TYPE_IS_FLOATING(T) BOOST_PP_TUPLE4_ELEM2 T +#define TYPE_RANK(T) BOOST_PP_TUPLE4_ELEM3 T -/* List of C built-in types. - * - * Some of the information is platform dependent, but this example - * does not take that into consideration. - */ +/* List of C built-in types. */ #define BUILTIN_TYPES\ BOOST_PP_TUPLE_TO_LIST\ ( 12\ - , ( ( signed char , sc , 0 , 0 , 1 )\ - , ( char , ch , 0 , 0 , 1 )\ - , ( unsigned char , uc , 0 , 1 , 1 )\ - , ( short , ss , 0 , 0 , 2 )\ - , ( unsigned short , us , 0 , 1 , 2 )\ + , ( ( 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 int , ui , 0 , 1 , 4 )\ - , ( long , sl , 0 , 0 , 5 )\ - , ( unsigned long , ul , 0 , 1 , 6 )\ - , ( float , fl , 1 , 0 , 7 )\ - , ( double , db , 1 , 0 , 8 )\ - , ( long double , ld , 1 , 0 , 9 )\ + , ( 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 operations. */ -#define TYPE_INT ( int , si , 0 , 0 , 3 ) +/* Type int is needed in some type computations. */ +#define TYPE_INT ( int , si , 0 , 3 ) -/* 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)) - -/* 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))) +/* 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 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)\ - BOOST_PP_IF\ - ( BOOST_PP_NOT_EQUAL(BOOST_PP_ADD(BOOST_PP_MUL(2,TYPE_IS_FLOATING(T)),OP_IS_FLOATING(O)),2)\ - , UNARY_ARRAY_OP3\ - , BOOST_PP_TUPLE2_EAT\ - )(O,T) +#define UNARY_ARRAY_OP(_,L) UNARY_ARRAY_OP2(BOOST_PP_LIST_AT(L,1),BOOST_PP_LIST_FIRST(L)) +#define UNARY_ARRAY_OP2(O,T) BOOST_PP_IF(IS_VALID_UNARY_OP_AND_TYPE_COMBINATION(O,T),UNARY_ARRAY_OP3,BOOST_PP_TUPLE2_EAT)(O,T) #define UNARY_ARRAY_OP3(O,T)\ void BOOST_PP_CAT4(array_,OP_NAME(O),_,TYPE_ABBREVIATION(T))\ - (const TYPE_NAME(T)* in, TYPE_NAME(UNARY_OP_RESULT(O,T))* out, size_t n)\ + (const TYPE_NAME(T)* in, TYPE_NAME(TYPE_OF_UNARY_OP(O,T))* out, size_t n)\ { do { *out++ = OP_SYMBOL(O) *in++; } while (--n); } BOOST_PP_LIST_FOR_EACH_PRODUCT(UNARY_ARRAY_OP,_,BOOST_PP_TUPLE_TO_LIST(2,(APPLICATIVE_UNARY_OPS,BUILTIN_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)\ - BOOST_PP_IF\ - ( BOOST_PP_NOT_EQUAL(BOOST_PP_ADD(BOOST_PP_MUL(2,BOOST_PP_OR(TYPE_IS_FLOATING(L),TYPE_IS_FLOATING(R))),OP_IS_FLOATING(O)),2)\ - , BINARY_ARRAY_OP3\ - , BOOST_PP_TUPLE3_EAT\ - )(O,L,R) +#define BINARY_ARRAY_OP(_,L) BINARY_ARRAY_OP2(BOOST_PP_LIST_AT(L,2),BOOST_PP_LIST_AT(L,1),BOOST_PP_LIST_FIRST(L)) +#define BINARY_ARRAY_OP2(O,L,R) BOOST_PP_IF(IS_VALID_BINARY_OP_AND_TYPE_COMBINATION(O,L,R),BINARY_ARRAY_OP3,BOOST_PP_TUPLE3_EAT)(O,L,R) #define BINARY_ARRAY_OP3(O,L,R)\ void BOOST_PP_CAT6(array_,OP_NAME(O),_,TYPE_ABBREVIATION(L),_,TYPE_ABBREVIATION(R))\ - (const TYPE_NAME(L)* lhs_in, const TYPE_NAME(R)* rhs_in, TYPE_NAME(BINARY_OP_RESULT(O,L,R))* out, size_t n)\ + (const TYPE_NAME(L)* lhs_in, const TYPE_NAME(R)* rhs_in, TYPE_NAME(TYPE_OF_BINARY_OP(O,L,R))* out, size_t n)\ { do { *out++ = *lhs_in++ OP_SYMBOL(O) *rhs_in++; } while (--n); } BOOST_PP_LIST_FOR_EACH_PRODUCT(BINARY_ARRAY_OP,_,BOOST_PP_TUPLE_TO_LIST(3,(APPLICATIVE_BINARY_OPS,BUILTIN_TYPES,BUILTIN_TYPES)))