diff options
author | Marius Vollmer <mvo@zagadka.de> | 2004-07-29 13:42:50 +0000 |
---|---|---|
committer | Marius Vollmer <mvo@zagadka.de> | 2004-07-29 13:42:50 +0000 |
commit | bfd7932e6644c91004c6e863ecc5db580eda12f6 (patch) | |
tree | 3dd36f35e219ffdf30122eff2f214e395d14f65f | |
parent | 3bfd202a72b19758b291219d7ef20c319ada2978 (diff) |
* conv-integer.i.c, conv-uinteger.i.c: New files, used to generate
the functions below.
* numbers.c, numbers.h (scm_to_int8, scm_to_uint8, scm_to_int16,
scm_to_uint16, scm_to_int32, scm_to_uint32, scm_to_int64,
scm_to_uint64, scm_from_int8, scm_from_uint8, scm_from_int16,
scm_from_uint16, scm_from_int32, scm_from_uint32, scm_from_int64,
scm_from_uint64): Turned from macros into proper functions.
(scm_to_signed_integer, scm_to_unsigned_integer,
scm_from_signed_integer, scm_from_unsigned_integer): Generate via
conv-integer.i.c and conv-uinteger.i.c, as well.
-rw-r--r-- | libguile/conv-integer.i.c | 126 | ||||
-rw-r--r-- | libguile/conv-uinteger.i.c | 95 | ||||
-rw-r--r-- | libguile/numbers.c | 259 | ||||
-rw-r--r-- | libguile/numbers.h | 68 |
4 files changed, 333 insertions, 215 deletions
diff --git a/libguile/conv-integer.i.c b/libguile/conv-integer.i.c new file mode 100644 index 000000000..4a6095fc1 --- /dev/null +++ b/libguile/conv-integer.i.c @@ -0,0 +1,126 @@ +TYPE +SCM_TO_TYPE_PROTO (SCM val) +{ + if (SCM_I_INUMP (val)) + { + scm_t_signed_bits n = SCM_I_INUM (val); +#if SIZEOF_TYPE != 0 && SIZEOF_TYPE > SIZEOF_SCM_T_BITS + return n; +#else + if (n >= TYPE_MIN && n <= TYPE_MAX) + return n; + else + { + goto out_of_range; + } +#endif + } + else if (SCM_BIGP (val)) + { + if (TYPE_MIN >= SCM_MOST_NEGATIVE_FIXNUM + && TYPE_MAX <= SCM_MOST_POSITIVE_FIXNUM) + goto out_of_range; + else if (TYPE_MIN >= LONG_MIN && TYPE_MAX <= LONG_MAX) + { + if (mpz_fits_slong_p (SCM_I_BIG_MPZ (val))) + { + long n = mpz_get_si (SCM_I_BIG_MPZ (val)); +#if SIZEOF_TYPE != 0 && SIZEOF_TYPE > SCM_SIZEOF_LONG + return n; +#else + if (n >= TYPE_MIN && n <= TYPE_MAX) + return n; + else + goto out_of_range; +#endif + } + else + goto out_of_range; + } + else + { + scm_t_intmax n; + size_t count; + + if (mpz_sizeinbase (SCM_I_BIG_MPZ (val), 2) + > CHAR_BIT*sizeof (scm_t_uintmax)) + goto out_of_range; + + mpz_export (&n, &count, 1, sizeof (scm_t_uintmax), 0, 0, + SCM_I_BIG_MPZ (val)); + + if (mpz_sgn (SCM_I_BIG_MPZ (val)) >= 0) + { + if (n < 0) + goto out_of_range; + } + else + { + n = -n; + if (n >= 0) + goto out_of_range; + } + + if (n >= TYPE_MIN && n <= TYPE_MAX) + return n; + else + { + out_of_range: + scm_out_of_range (NULL, val); + return 0; + } + } + } + else + { + scm_wrong_type_arg_msg (NULL, 0, val, "exact integer"); + return 0; + } +} + +SCM +SCM_FROM_TYPE_PROTO (TYPE val) +{ +#if SIZEOF_TYPE != 0 && SIZEOF_TYPE < SIZEOF_SCM_T_BITS + return SCM_I_MAKINUM (val); +#else + if (SCM_FIXABLE (val)) + return SCM_I_MAKINUM (val); + else if (val >= LONG_MIN && val <= LONG_MAX) + { + SCM z = scm_double_cell (scm_tc16_big, 0, 0, 0); + mpz_init_set_si (SCM_I_BIG_MPZ (z), val); + return z; + } + else + { + SCM z = scm_double_cell (scm_tc16_big, 0, 0, 0); + mpz_init (SCM_I_BIG_MPZ (z)); + if (val < 0) + { + val = -val; + mpz_import (SCM_I_BIG_MPZ (z), 1, 1, sizeof (TYPE), 0, 0, + &val); + mpz_neg (SCM_I_BIG_MPZ (z), SCM_I_BIG_MPZ (z)); + } + else + mpz_import (SCM_I_BIG_MPZ (z), 1, 1, sizeof (TYPE), 0, 0, + &val); + return z; + } +#endif +} + +/* clean up */ +#undef TYPE +#undef TYPE_MIN +#undef TYPE_MAX +#undef SIZEOF_TYPE +#undef SCM_TO_TYPE_PROTO +#undef SCM_FROM_TYPE_PROTO + +/* + Local Variables: + c-file-style: "gnu" + End: +*/ diff --git a/libguile/conv-uinteger.i.c b/libguile/conv-uinteger.i.c new file mode 100644 index 000000000..961000449 --- /dev/null +++ b/libguile/conv-uinteger.i.c @@ -0,0 +1,95 @@ +TYPE +SCM_TO_TYPE_PROTO (SCM val) +{ + if (SCM_I_INUMP (val)) + { + scm_t_signed_bits n = SCM_I_INUM (val); + if (n >= 0 + && ((scm_t_uintmax)n) >= TYPE_MIN && ((scm_t_uintmax)n) <= TYPE_MAX) + return n; + else + { + out_of_range: + scm_out_of_range (NULL, val); + return 0; + } + } + else if (SCM_BIGP (val)) + { + if (TYPE_MAX <= SCM_MOST_POSITIVE_FIXNUM) + goto out_of_range; + else if (TYPE_MAX <= ULONG_MAX) + { + if (mpz_fits_ulong_p (SCM_I_BIG_MPZ (val))) + { + unsigned long n = mpz_get_ui (SCM_I_BIG_MPZ (val)); +#if SIZEOF_TYPE != 0 && SIZEOF_TYPE > SCM_SIZEOF_LONG + return n; +#else + if (n >= TYPE_MIN && n <= TYPE_MAX) + return n; + else + goto out_of_range; +#endif + } + else + goto out_of_range; + } + else + { + scm_t_uintmax n; + size_t count; + + if (mpz_sgn (SCM_I_BIG_MPZ (val)) < 0) + goto out_of_range; + + if (mpz_sizeinbase (SCM_I_BIG_MPZ (val), 2) + > CHAR_BIT*sizeof (TYPE)) + goto out_of_range; + + mpz_export (&n, &count, 1, sizeof (TYPE), 0, 0, SCM_I_BIG_MPZ (val)); + + if (n >= TYPE_MIN && n <= TYPE_MAX) + return n; + else + goto out_of_range; + } + } + else + { + scm_wrong_type_arg_msg (NULL, 0, val, "exact integer"); + return 0; + } +} + +SCM +SCM_FROM_TYPE_PROTO (TYPE val) +{ +#if SIZEOF_TYPE != 0 && SIZEOF_TYPE < SIZEOF_SCM_T_BITS + return SCM_I_MAKINUM (val); +#else + if (SCM_POSFIXABLE (val)) + return SCM_I_MAKINUM (val); + else if (val <= ULONG_MAX) + { + SCM z = scm_double_cell (scm_tc16_big, 0, 0, 0); + mpz_init_set_ui (SCM_I_BIG_MPZ (z), val); + return z; + } + else + { + SCM z = scm_double_cell (scm_tc16_big, 0, 0, 0); + mpz_init (SCM_I_BIG_MPZ (z)); + mpz_import (SCM_I_BIG_MPZ (z), 1, 1, sizeof (TYPE), 0, 0, &val); + return z; + } +#endif +} + +#undef TYPE +#undef TYPE_MIN +#undef TYPE_MAX +#undef SIZEOF_TYPE +#undef SCM_TO_TYPE_PROTO +#undef SCM_FROM_TYPE_PROTO + diff --git a/libguile/numbers.c b/libguile/numbers.c index f57ed0805..6ca389c95 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -5750,184 +5750,89 @@ scm_is_unsigned_integer (SCM val, scm_t_uintmax min, scm_t_uintmax max) return 0; } -scm_t_intmax -scm_to_signed_integer (SCM val, scm_t_intmax min, scm_t_intmax max) -{ - if (SCM_I_INUMP (val)) - { - scm_t_signed_bits n = SCM_I_INUM (val); - if (n >= min && n <= max) - return n; - else - { - out_of_range: - scm_out_of_range (NULL, val); - return 0; - } - } - else if (SCM_BIGP (val)) - { - if (min >= SCM_MOST_NEGATIVE_FIXNUM && max <= SCM_MOST_POSITIVE_FIXNUM) - goto out_of_range; - else if (min >= LONG_MIN && max <= LONG_MAX) - { - if (mpz_fits_slong_p (SCM_I_BIG_MPZ (val))) - { - long n = mpz_get_si (SCM_I_BIG_MPZ (val)); - if (n >= min && n <= max) - return n; - else - goto out_of_range; - } - else - goto out_of_range; - } - else - { - scm_t_intmax n; - size_t count; - - if (mpz_sizeinbase (SCM_I_BIG_MPZ (val), 2) - > CHAR_BIT*sizeof (scm_t_uintmax)) - goto out_of_range; - - mpz_export (&n, &count, 1, sizeof (scm_t_uintmax), 0, 0, - SCM_I_BIG_MPZ (val)); +#define TYPE scm_t_intmax +#define TYPE_MIN min +#define TYPE_MAX max +#define SIZEOF_TYPE 0 +#define SCM_TO_TYPE_PROTO(arg) scm_to_signed_integer (arg, scm_t_intmax min, scm_t_intmax max) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_signed_integer (arg) +#include "libguile/conv-integer.i.c" + +#define TYPE scm_t_uintmax +#define TYPE_MIN min +#define TYPE_MAX max +#define SIZEOF_TYPE 0 +#define SCM_TO_TYPE_PROTO(arg) scm_to_unsigned_integer (arg, scm_t_uintmax min, scm_t_uintmax max) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_unsigned_integer (arg) +#include "libguile/conv-uinteger.i.c" + +#define TYPE scm_t_int8 +#define TYPE_MIN SCM_T_INT8_MIN +#define TYPE_MAX SCM_T_INT8_MAX +#define SIZEOF_TYPE 1 +#define SCM_TO_TYPE_PROTO(arg) scm_to_int8 (arg) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_int8 (arg) +#include "libguile/conv-integer.i.c" + +#define TYPE scm_t_uint8 +#define TYPE_MIN 0 +#define TYPE_MAX SCM_T_UINT8_MAX +#define SIZEOF_TYPE 1 +#define SCM_TO_TYPE_PROTO(arg) scm_to_uint8 (arg) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_uint8 (arg) +#include "libguile/conv-uinteger.i.c" + +#define TYPE scm_t_int16 +#define TYPE_MIN SCM_T_INT16_MIN +#define TYPE_MAX SCM_T_INT16_MAX +#define SIZEOF_TYPE 2 +#define SCM_TO_TYPE_PROTO(arg) scm_to_int16 (arg) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_int16 (arg) +#include "libguile/conv-integer.i.c" + +#define TYPE scm_t_uint16 +#define TYPE_MIN 0 +#define TYPE_MAX SCM_T_UINT16_MAX +#define SIZEOF_TYPE 2 +#define SCM_TO_TYPE_PROTO(arg) scm_to_uint16 (arg) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_uint16 (arg) +#include "libguile/conv-uinteger.i.c" + +#define TYPE scm_t_int32 +#define TYPE_MIN SCM_T_INT32_MIN +#define TYPE_MAX SCM_T_INT32_MAX +#define SIZEOF_TYPE 4 +#define SCM_TO_TYPE_PROTO(arg) scm_to_int32 (arg) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_int32 (arg) +#include "libguile/conv-integer.i.c" + +#define TYPE scm_t_uint32 +#define TYPE_MIN 0 +#define TYPE_MAX SCM_T_UINT32_MAX +#define SIZEOF_TYPE 4 +#define SCM_TO_TYPE_PROTO(arg) scm_to_uint32 (arg) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_uint32 (arg) +#include "libguile/conv-uinteger.i.c" + +#if SCM_HAVE_T_INT64 + +#define TYPE scm_t_int64 +#define TYPE_MIN SCM_T_INT64_MIN +#define TYPE_MAX SCM_T_INT64_MAX +#define SIZEOF_TYPE 8 +#define SCM_TO_TYPE_PROTO(arg) scm_to_int64 (arg) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_int64 (arg) +#include "libguile/conv-integer.i.c" + +#define TYPE scm_t_uint64 +#define TYPE_MIN 0 +#define TYPE_MAX SCM_T_UINT64_MAX +#define SIZEOF_TYPE 8 +#define SCM_TO_TYPE_PROTO(arg) scm_to_uint64 (arg) +#define SCM_FROM_TYPE_PROTO(arg) scm_from_uint64 (arg) +#include "libguile/conv-uinteger.i.c" - if (mpz_sgn (SCM_I_BIG_MPZ (val)) >= 0) - { - if (n < 0) - goto out_of_range; - } - else - { - n = -n; - if (n >= 0) - goto out_of_range; - } - - if (n >= min && n <= max) - return n; - else - goto out_of_range; - } - } - else - { - scm_wrong_type_arg_msg (NULL, 0, val, "exact integer"); - return 0; - } -} - -scm_t_uintmax -scm_to_unsigned_integer (SCM val, scm_t_uintmax min, scm_t_uintmax max) -{ - if (SCM_I_INUMP (val)) - { - scm_t_signed_bits n = SCM_I_INUM (val); - if (n >= 0 && ((scm_t_uintmax)n) >= min && ((scm_t_uintmax)n) <= max) - return n; - else - { - out_of_range: - scm_out_of_range (NULL, val); - return 0; - } - } - else if (SCM_BIGP (val)) - { - if (max <= SCM_MOST_POSITIVE_FIXNUM) - goto out_of_range; - else if (max <= ULONG_MAX) - { - if (mpz_fits_ulong_p (SCM_I_BIG_MPZ (val))) - { - unsigned long n = mpz_get_ui (SCM_I_BIG_MPZ (val)); - if (n >= min && n <= max) - return n; - else - goto out_of_range; - } - else - goto out_of_range; - } - else - { - scm_t_uintmax n; - size_t count; - - if (mpz_sgn (SCM_I_BIG_MPZ (val)) < 0) - goto out_of_range; - - if (mpz_sizeinbase (SCM_I_BIG_MPZ (val), 2) - > CHAR_BIT*sizeof (scm_t_uintmax)) - goto out_of_range; - - mpz_export (&n, &count, 1, sizeof (scm_t_uintmax), 0, 0, - SCM_I_BIG_MPZ (val)); - - if (n >= min && n <= max) - return n; - else - goto out_of_range; - } - } - else - { - scm_wrong_type_arg_msg (NULL, 0, val, "exact integer"); - return 0; - } -} - -SCM -scm_from_signed_integer (scm_t_intmax val) -{ - if (SCM_FIXABLE (val)) - return SCM_I_MAKINUM (val); - else if (val >= LONG_MIN && val <= LONG_MAX) - { - SCM z = scm_double_cell (scm_tc16_big, 0, 0, 0); - mpz_init_set_si (SCM_I_BIG_MPZ (z), val); - return z; - } - else - { - SCM z = scm_double_cell (scm_tc16_big, 0, 0, 0); - mpz_init (SCM_I_BIG_MPZ (z)); - if (val < 0) - { - val = -val; - mpz_import (SCM_I_BIG_MPZ (z), 1, 1, sizeof (scm_t_intmax), 0, 0, - &val); - mpz_neg (SCM_I_BIG_MPZ (z), SCM_I_BIG_MPZ (z)); - } - else - mpz_import (SCM_I_BIG_MPZ (z), 1, 1, sizeof (scm_t_intmax), 0, 0, - &val); - return z; - } -} - -SCM -scm_from_unsigned_integer (scm_t_uintmax val) -{ - if (SCM_POSFIXABLE (val)) - return SCM_I_MAKINUM (val); - else if (val <= ULONG_MAX) - { - SCM z = scm_double_cell (scm_tc16_big, 0, 0, 0); - mpz_init_set_ui (SCM_I_BIG_MPZ (z), val); - return z; - } - else - { - SCM z = scm_double_cell (scm_tc16_big, 0, 0, 0); - mpz_init (SCM_I_BIG_MPZ (z)); - mpz_import (SCM_I_BIG_MPZ (z), 1, 1, sizeof (scm_t_uintmax), 0, 0, - &val); - return z; - } -} +#endif int scm_is_real (SCM val) diff --git a/libguile/numbers.h b/libguile/numbers.h index 405b80bf0..8e4d82c28 100644 --- a/libguile/numbers.h +++ b/libguile/numbers.h @@ -356,6 +356,34 @@ SCM_API scm_t_uintmax scm_to_unsigned_integer (SCM val, scm_t_uintmax min, scm_t_uintmax max); +SCM_API scm_t_int8 scm_to_int8 (SCM x); +SCM_API SCM scm_from_int8 (scm_t_int8 x); + +SCM_API scm_t_uint8 scm_to_uint8 (SCM x); +SCM_API SCM scm_from_uint8 (scm_t_uint8 x); + +SCM_API scm_t_int16 scm_to_int16 (SCM x); +SCM_API SCM scm_from_int16 (scm_t_int16 x); + +SCM_API scm_t_uint16 scm_to_uint16 (SCM x); +SCM_API SCM scm_from_uint16 (scm_t_uint16 x); + +SCM_API scm_t_int32 scm_to_int32 (SCM x); +SCM_API SCM scm_from_int32 (scm_t_int32 x); + +SCM_API scm_t_uint32 scm_to_uint32 (SCM x); +SCM_API SCM scm_from_uint32 (scm_t_uint32 x); + +#if SCM_HAVE_T_INT64 + +SCM_API scm_t_int64 scm_to_int64 (SCM x); +SCM_API SCM scm_from_int64 (scm_t_int64 x); + +SCM_API scm_t_uint64 scm_to_uint64 (SCM x); +SCM_API SCM scm_from_uint64 (scm_t_uint64 x); + +#endif + #define scm_to_schar(x) \ ((signed char)scm_to_signed_integer ((x), SCHAR_MIN, SCHAR_MAX)) #define scm_to_uchar(x) \ @@ -382,9 +410,9 @@ SCM_API scm_t_uintmax scm_to_unsigned_integer (SCM val, ((unsigned long)scm_to_unsigned_integer ((x), 0, ULONG_MAX)) #define scm_to_ssize_t(x) \ - ((ssize_t)scm_to_signed_integer ((x), -SSIZE_MAX-1, SSIZE_MAX)) + ((ssize_t)scm_to_signed_integer ((x), SCM_I_SSIZE_MIN, SCM_I_SSIZE_MAX)) #define scm_to_size_t(x) \ - ((unsigned long)scm_to_unsigned_integer ((x), 0, SIZE_MAX)) + ((unsigned long)scm_to_unsigned_integer ((x), 0, SCM_I_SIZE_MAX)) #if SCM_SIZEOF_LONG_LONG != 0 #define scm_to_long_long(x) \ @@ -393,28 +421,6 @@ SCM_API scm_t_uintmax scm_to_unsigned_integer (SCM val, ((unsigned long long)scm_to_unsigned_integer ((x), 0, SCM_I_ULLONG_MAX)) #endif -#define scm_to_int8(x) \ - ((scm_t_int8)scm_to_signed_integer ((x), SCM_T_INT8_MIN, SCM_T_INT8_MAX)) -#define scm_to_uint8(x) \ - ((scm_t_uint8)scm_to_unsigned_integer ((x), 0, SCM_T_UINT8_MAX)) - -#define scm_to_int16(x) \ - ((scm_t_int16)scm_to_signed_integer ((x), SCM_T_INT16_MIN, SCM_T_INT16_MAX)) -#define scm_to_uint16(x) \ - ((scm_t_uint16)scm_to_unsigned_integer ((x), 0, SCM_T_UINT16_MAX)) - -#define scm_to_int32(x) \ - ((scm_t_int32)scm_to_signed_integer ((x), SCM_T_INT32_MIN, SCM_T_INT32_MAX)) -#define scm_to_uint32(x) \ - ((scm_t_uint32)scm_to_unsigned_integer ((x), 0, SCM_T_UINT32_MAX)) - -#if SCM_HAVE_T_INT64 -#define scm_to_int64(x) \ - ((scm_t_int64)scm_to_signed_integer ((x), SCM_T_INT64_MIN, SCM_T_INT64_MAX)) -#define scm_to_uint64(x) \ - ((scm_t_uint64)scm_to_unsigned_integer ((x), 0, SCM_T_UINT64_MAX)) -#endif - #define scm_to_intmax(x) \ ((scm_t_intmax)scm_to_signed_integer ((x),SCM_T_INTMAX_MIN,SCM_T_INTMAX_MAX)) #define scm_to_uintmax(x) \ @@ -445,20 +451,6 @@ SCM_API scm_t_uintmax scm_to_unsigned_integer (SCM val, #define scm_from_ulong_long(x) scm_from_unsigned_integer ((unsigned long long)(x)) #endif -#define scm_from_int8(x) scm_from_signed_integer ((scm_t_int8)(x)) -#define scm_from_uint8(x) scm_from_unsigned_integer ((scm_t_uint8)(x)) - -#define scm_from_int16(x) scm_from_signed_integer ((scm_t_int16)(x)) -#define scm_from_uint16(x) scm_from_unsigned_integer ((scm_t_uint16)(x)) - -#define scm_from_int32(x) scm_from_signed_integer ((scm_t_int32)(x)) -#define scm_from_uint32(x) scm_from_unsigned_integer ((scm_t_uint32)(x)) - -#if SCM_HAVE_T_INT64 -#define scm_from_int64(x) scm_from_signed_integer ((scm_t_int64)(x)) -#define scm_from_uint64(x) scm_from_unsigned_integer ((scm_t_uint64)(x)) -#endif - #define scm_from_intmax(x) scm_from_signed_integer ((scm_t_intmax)(x)) #define scm_from_uintmax(x) scm_from_unsigned_integer ((scm_t_uintmax)(x)) |