aboutsummaryrefslogtreecommitdiffstats
path: root/zahl.h
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2016-04-07 16:04:07 +0200
committerMattias Andrée <maandree@kth.se>2016-04-07 16:04:07 +0200
commit8d82bea597a2969db0780e3142437ea91929613f (patch)
tree71d9dbf04a53e22eef9433c0ae09cf83ae3997e8 /zahl.h
parentzptest: use DEFAULT_RANDOM (diff)
downloadlibzahl-8d82bea597a2969db0780e3142437ea91929613f.tar.gz
libzahl-8d82bea597a2969db0780e3142437ea91929613f.tar.bz2
libzahl-8d82bea597a2969db0780e3142437ea91929613f.tar.xz
Split out zahl-inlines.h zahl-internals.h from zahl.h to hide uninteresting stuff
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'zahl.h')
-rw-r--r--zahl.h251
1 files changed, 2 insertions, 249 deletions
diff --git a/zahl.h b/zahl.h
index 6e30510..2df05e7 100644
--- a/zahl.h
+++ b/zahl.h
@@ -12,21 +12,10 @@
#include <stdint.h>
#include <limits.h>
-
-
-#ifndef ZAHL_INLINE
-# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-# define ZAHL_INLINE static inline
-# else
-# define ZAHL_INLINE static
-# endif
-#endif
+#include "zahl-internals.h"
-/* You should pretend like this typedef does not exist. */
-typedef uint64_t zahl_char_t;
-
/* This structure should be considered opaque. */
typedef struct {
int sign;
@@ -185,242 +174,6 @@ void zperror(const char *); /* Identical to perror(3p) except it sup
-/* ------------------------------- Implementations of inline functions. ------------------------------- */
-
-
-#if defined(__GNUC__) || defined(__clang__)
-# define ZAHL_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
-# define ZAHL_LIKELY(expr) __builtin_expect(!!(expr), 1)
-#else
-# define ZAHL_UNLIKELY(expr) (expr)
-# define ZAHL_LIKELY(expr) (expr)
-#endif
-
-
-ZAHL_INLINE void zinit(z_t a) { a->alloced = 0; a->chars = 0; }
-ZAHL_INLINE int zeven(z_t a) { return !a->sign || !(a->chars[0] & 1); }
-ZAHL_INLINE int zodd(z_t a) { return a->sign && (a->chars[0] & 1); }
-ZAHL_INLINE int zeven_nonzero(z_t a) { return !(a->chars[0] & 1); }
-ZAHL_INLINE int zodd_nonzero(z_t a) { return (a->chars[0] & 1); }
-ZAHL_INLINE int zzero(z_t a) { return !a->sign; }
-ZAHL_INLINE int zsignum(z_t a) { return a->sign; }
-ZAHL_INLINE void zabs(z_t a, z_t b) { if (a != b) zset(a, b); a->sign = !!a->sign; }
-ZAHL_INLINE void zneg(z_t a, z_t b) { if (a != b) zset(a, b); a->sign = -a->sign; }
-
-
-ZAHL_INLINE void
-zswap(z_t a, z_t b)
-{
- z_t t;
- t->sign = a->sign;
- a->sign = b->sign;
- b->sign = t->sign;
- t->used = b->used;
- b->used = a->used;
- a->used = t->used;
- t->alloced = a->alloced;
- a->alloced = b->alloced;
- b->alloced = t->alloced;
- t->chars = b->chars;
- b->chars = a->chars;
- a->chars = t->chars;
-}
-
-
-ZAHL_INLINE void
-zseti(z_t a, int64_t b)
-{
- if (ZAHL_UNLIKELY(b >= 0)) {
- zsetu(a, (uint64_t)b);
- } else {
- zsetu(a, (uint64_t)-b);
- a->sign = -1;
- }
-}
-
-
-ZAHL_INLINE size_t
-zlsb(z_t a)
-{
-#if defined(__GNUC__) || defined(__clang__)
- size_t i = 0;
- if (ZAHL_UNLIKELY(zzero(a)))
- return SIZE_MAX;
- for (; !a->chars[i]; i++);
- i *= 8 * sizeof(zahl_char_t);
- i += (size_t)__builtin_ctzll(a->chars[i]);
- return i;
-#else
- size_t i = 0;
- zahl_char_t x;
- if (ZAHL_UNLIKELY(zzero(a)))
- return SIZE_MAX;
- for (; !a->chars[i]; i++);
- i *= 8 * sizeof(zahl_char_t);
- x = ~(a->chars[i]);
- for (; x & 1; x >>= 1, i++);
- return i;
-#endif
-}
-
-
-ZAHL_INLINE size_t
-zbits(z_t a)
-{
-#if defined(__GNUC__) || defined(__clang__)
- size_t rc;
- if (ZAHL_UNLIKELY(zzero(a)))
- return 1;
- while (!a->chars[a->used - 1]) a->used--; /* TODO should not be necessary */
- rc = a->used * 8 * sizeof(zahl_char_t);
- rc -= (size_t)__builtin_clzll(a->chars[a->used - 1]);
- return rc;
-#else
- size_t rc;
- zahl_char_t x;
- if (ZAHL_UNLIKELY(zzero(a)))
- return 1;
- while (!a->chars[a->used - 1]) a->used--; /* TODO should not be necessary */
- x = a->chars[a->used - 1];
- rc = (a->used - 1) * 8 * sizeof(zahl_char_t);
- for (; x; x >>= 1, rc++);
- return rc;
-#endif
-}
-
-
-ZAHL_INLINE int
-zcmpmag(z_t a, z_t b)
-{
- size_t i, j;
- if (ZAHL_UNLIKELY(zzero(a)))
- return -!zzero(b);
- if (ZAHL_UNLIKELY(zzero(b)))
- return 1;
- i = a->used - 1;
- j = b->used - 1;
-#if 0 /* TODO this should be sufficient. */
- if (i != j)
- return (i > j) * 2 - 1;
-#else
- for (; i > j; i--) {
- if (a->chars[i])
- return +1;
- a->used--;
- }
- for (; j > i; j--) {
- if (b->chars[j])
- return -1;
- b->used--;
- }
-#endif
- for (; i && a->chars[i] == b->chars[i]; i--);
- return a->chars[i] < b->chars[i] ? -1 : a->chars[i] > b->chars[i];
-}
-
-
-ZAHL_INLINE int
-zcmp(z_t a, z_t b)
-{
- if (zsignum(a) != zsignum(b))
- return zsignum(a) < zsignum(b) ? -1 : zsignum(a) > zsignum(b);
- return zsignum(a) * zcmpmag(a, b);
-}
-
-
-ZAHL_INLINE int
-zcmpu(z_t a, uint64_t b)
-{
- extern z_t libzahl_tmp_cmp;
- if (ZAHL_UNLIKELY(!b))
- return zsignum(a);
- if (ZAHL_UNLIKELY(zsignum(a) <= 0))
- return -1;
- libzahl_tmp_cmp->chars[0] = b;
- return zcmpmag(a, libzahl_tmp_cmp);
-}
-
-
-ZAHL_INLINE int
-zcmpi(z_t a, int64_t b)
-{
- extern z_t libzahl_tmp_cmp;
- if (ZAHL_UNLIKELY(!b))
- return zsignum(a);
- if (ZAHL_UNLIKELY(zzero(a)))
- return ZAHL_LIKELY(b < 0) ? 1 : -1;
- if (ZAHL_LIKELY(b < 0)) {
- if (zsignum(a) > 0)
- return +1;
- libzahl_tmp_cmp->chars[0] = (uint64_t)-b;
- return -zcmpmag(a, libzahl_tmp_cmp);
- } else {
- if (zsignum(a) < 0)
- return -1;
- libzahl_tmp_cmp->chars[0] = b;
- return +zcmpmag(a, libzahl_tmp_cmp);
- }
-}
-
-
-void zbset_impl_set(z_t a, z_t b, size_t bit);
-void zbset_impl_clear(z_t a, z_t b, size_t bit);
-void zbset_impl_flip(z_t a, z_t b, size_t bit);
-ZAHL_INLINE void
-zbset(z_t a, z_t b, size_t bit, int action)
-{
- if (ZAHL_UNLIKELY(a != b))
- zset(a, b);
-
-#if defined(__GNUC__) || defined(__clang__)
- if (__builtin_constant_p(action) && __builtin_constant_p(bit)) {
- zahl_char_t mask = 1;
- if (zzero(a) || bit >> 6 >= a->used) {
- if (!action)
- return;
- goto fallback;
- }
- mask <<= bit & 63;
- if (action > 0) {
- a->chars[bit >> 6] |= mask;
- return;
- } else if (action < 0) {
- a->chars[bit >> 6] ^= mask;
- } else {
- a->chars[bit >> 6] &= ~mask;
- }
- for (; a->used && !a->chars[a->used - 1]; a->used--);
- if (!a->used)
- a->sign = 0;
- return;
- }
-fallback:
-#endif
-
- if (action > 0) {
- zbset_impl_set(a, b, bit);
- } else if (action < 0) {
- zbset_impl_flip(a, b, bit);
- } else {
- zbset_impl_clear(a, b, bit);
- }
-}
-
-
-ZAHL_INLINE int
-zbtest(z_t a, size_t bit)
-{
- size_t chars;
- if (ZAHL_UNLIKELY(zzero(a)))
- return 0;
-
- chars = bit >> 6;
- if (ZAHL_UNLIKELY(chars >= a->used))
- return 0;
-
- bit &= 63;
- return (a->chars[chars] >> bit) & 1;
-}
-
+#include "zahl-inlines.h"
#endif