mirror of
https://github.com/boostorg/preprocessor.git
synced 2025-07-10 03:06:29 +02:00
152 lines
5.6 KiB
C
152 lines
5.6 KiB
C
/* Copyright (C) 2002
|
|
* Housemarque Oy
|
|
* http://www.housemarque.com
|
|
*
|
|
* Permission to copy, use, modify, sell and distribute this software is
|
|
* granted provided this copyright notice appears in all copies. This
|
|
* software is provided "as is" without express or implied warranty, and
|
|
* with no claim as to its suitability for any purpose.
|
|
*
|
|
* 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/list/for_each_product.hpp>
|
|
#include <boost/preprocessor/list/at.hpp>
|
|
#include <boost/preprocessor/list/cat.hpp>
|
|
#include <boost/preprocessor/list/append.hpp>
|
|
#include <boost/preprocessor/tuple/to_list.hpp>
|
|
#include <boost/preprocessor/tuple/eat.hpp>
|
|
#include <boost/preprocessor/comparison/less.hpp>
|
|
#include <boost/preprocessor/logical/or.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_LIST_APPEND\
|
|
( BOOST_PP_TUPLE_TO_LIST\
|
|
( 2\
|
|
, ( ( * , mul , 1 , 0 , 0 )\
|
|
, ( / , div , 1 , 0 , 0 )\
|
|
)\
|
|
)\
|
|
, BOOST_PP_TUPLE_TO_LIST\
|
|
( 16\
|
|
, ( ( % , 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 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_TUPLE2_EAT) 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_TUPLE3_EAT) 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))
|