/* -*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*- */ /* vim: set filetype=c tabstop=8 shiftwidth=4 expandtab: */ /* math_dispatch.h -- fast dispatch for math functions */ /* Copyright (c) 2010, Juan Jose Garcia Ripoll. ECL is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See file '../Copyright' for full details. */ #ifndef ECL_MATH_DISPATCH2_H #define ECL_MATH_DISPATCH2_H #include /* for unlikely_if */ #define MATH_DISPATCH2_LABEL(t1,t2) case ((t1)*(t_complex+1)+(t2)): #define MATH_DISPATCH2_BEGIN(x,y) { \ int tx = ecl_t_of(x), ty = ecl_t_of(y); \ unlikely_if (ty > t_complex) { goto DISPATCH2_ERROR; } \ switch (tx * (t_complex+1) + ty) #define MATH_DISPATCH2_END } (void)0 #define CASE_COMPLEX_FIXNUM \ MATH_DISPATCH2_LABEL(t_complex,t_fixnum) #define CASE_COMPLEX_BIGNUM \ MATH_DISPATCH2_LABEL(t_complex,t_bignum) #define CASE_COMPLEX_RATIO \ MATH_DISPATCH2_LABEL(t_complex,t_ratio) #define CASE_COMPLEX_SINGLE_FLOAT \ MATH_DISPATCH2_LABEL(t_complex,t_singlefloat) #define CASE_COMPLEX_DOUBLE_FLOAT \ MATH_DISPATCH2_LABEL(t_complex,t_doublefloat) #define CASE_COMPLEX_LONG_FLOAT \ MATH_DISPATCH2_LABEL(t_complex,t_longfloat) #define CASE_COMPLEX_COMPLEX \ MATH_DISPATCH2_LABEL(t_complex,t_complex) #define CASE_LONG_FLOAT_FIXNUM \ MATH_DISPATCH2_LABEL(t_longfloat,t_fixnum) #define CASE_LONG_FLOAT_BIGNUM \ MATH_DISPATCH2_LABEL(t_longfloat,t_bignum) #define CASE_LONG_FLOAT_RATIO \ MATH_DISPATCH2_LABEL(t_longfloat,t_ratio) #define CASE_LONG_FLOAT_SINGLE_FLOAT \ MATH_DISPATCH2_LABEL(t_longfloat,t_singlefloat) #define CASE_LONG_FLOAT_DOUBLE_FLOAT \ MATH_DISPATCH2_LABEL(t_longfloat,t_doublefloat) #define CASE_LONG_FLOAT_LONG_FLOAT \ MATH_DISPATCH2_LABEL(t_longfloat,t_longfloat) #define CASE_LONG_FLOAT_COMPLEX \ MATH_DISPATCH2_LABEL(t_longfloat,t_complex) #define CASE_DOUBLE_FLOAT_FIXNUM \ MATH_DISPATCH2_LABEL(t_doublefloat,t_fixnum) #define CASE_DOUBLE_FLOAT_BIGNUM \ MATH_DISPATCH2_LABEL(t_doublefloat,t_bignum) #define CASE_DOUBLE_FLOAT_RATIO \ MATH_DISPATCH2_LABEL(t_doublefloat,t_ratio) #define CASE_DOUBLE_FLOAT_SINGLE_FLOAT \ MATH_DISPATCH2_LABEL(t_doublefloat,t_singlefloat) #define CASE_DOUBLE_FLOAT_DOUBLE_FLOAT \ MATH_DISPATCH2_LABEL(t_doublefloat,t_doublefloat) #define CASE_DOUBLE_FLOAT_LONG_FLOAT \ MATH_DISPATCH2_LABEL(t_doublefloat,t_longfloat) #define CASE_DOUBLE_FLOAT_COMPLEX \ MATH_DISPATCH2_LABEL(t_doublefloat,t_complex) #define CASE_SINGLE_FLOAT_FIXNUM \ MATH_DISPATCH2_LABEL(t_singlefloat,t_fixnum) #define CASE_SINGLE_FLOAT_BIGNUM \ MATH_DISPATCH2_LABEL(t_singlefloat,t_bignum) #define CASE_SINGLE_FLOAT_RATIO \ MATH_DISPATCH2_LABEL(t_singlefloat,t_ratio) #define CASE_SINGLE_FLOAT_SINGLE_FLOAT \ MATH_DISPATCH2_LABEL(t_singlefloat,t_singlefloat) #define CASE_SINGLE_FLOAT_DOUBLE_FLOAT \ MATH_DISPATCH2_LABEL(t_singlefloat,t_doublefloat) #define CASE_SINGLE_FLOAT_LONG_FLOAT \ MATH_DISPATCH2_LABEL(t_singlefloat,t_longfloat) #define CASE_SINGLE_FLOAT_COMPLEX \ MATH_DISPATCH2_LABEL(t_singlefloat,t_complex) #define CASE_RATIO_FIXNUM \ MATH_DISPATCH2_LABEL(t_ratio,t_fixnum) #define CASE_RATIO_BIGNUM \ MATH_DISPATCH2_LABEL(t_ratio,t_bignum) #define CASE_RATIO_RATIO \ MATH_DISPATCH2_LABEL(t_ratio,t_ratio) #define CASE_RATIO_SINGLE_FLOAT \ MATH_DISPATCH2_LABEL(t_ratio,t_singlefloat) #define CASE_RATIO_DOUBLE_FLOAT \ MATH_DISPATCH2_LABEL(t_ratio,t_doublefloat) #define CASE_RATIO_LONG_FLOAT \ MATH_DISPATCH2_LABEL(t_ratio,t_longfloat) #define CASE_RATIO_COMPLEX \ MATH_DISPATCH2_LABEL(t_ratio,t_complex) #define CASE_BIGNUM_FIXNUM \ MATH_DISPATCH2_LABEL(t_bignum,t_fixnum) #define CASE_BIGNUM_BIGNUM \ MATH_DISPATCH2_LABEL(t_bignum,t_bignum) #define CASE_BIGNUM_RATIO \ MATH_DISPATCH2_LABEL(t_bignum,t_ratio) #define CASE_BIGNUM_SINGLE_FLOAT \ MATH_DISPATCH2_LABEL(t_bignum,t_singlefloat) #define CASE_BIGNUM_DOUBLE_FLOAT \ MATH_DISPATCH2_LABEL(t_bignum,t_doublefloat) #define CASE_BIGNUM_LONG_FLOAT \ MATH_DISPATCH2_LABEL(t_bignum,t_longfloat) #define CASE_BIGNUM_COMPLEX \ MATH_DISPATCH2_LABEL(t_bignum,t_complex) #define CASE_FIXNUM_FIXNUM \ MATH_DISPATCH2_LABEL(t_fixnum,t_fixnum) #define CASE_FIXNUM_BIGNUM \ MATH_DISPATCH2_LABEL(t_fixnum,t_bignum) #define CASE_FIXNUM_RATIO \ MATH_DISPATCH2_LABEL(t_fixnum,t_ratio) #define CASE_FIXNUM_SINGLE_FLOAT \ MATH_DISPATCH2_LABEL(t_fixnum,t_singlefloat) #define CASE_FIXNUM_DOUBLE_FLOAT \ MATH_DISPATCH2_LABEL(t_fixnum,t_doublefloat) #define CASE_FIXNUM_LONG_FLOAT \ MATH_DISPATCH2_LABEL(t_fixnum,t_longfloat) #define CASE_FIXNUM_COMPLEX \ MATH_DISPATCH2_LABEL(t_fixnum,t_complex) #define CASE_UNKNOWN(routine,x,y,type) \ default: DISPATCH2_ERROR: \ if (!ecl_numberp(x)) \ FEwrong_type_nth_arg(routine, 1, x, type); \ else \ FEwrong_type_nth_arg(routine, 2, y, type) #endif /* ECL_MATH_DISPATCH2_H */