Add separate 32/64 bit versions to guf_rand
This commit is contained in:
parent
05f995e855
commit
d062784425
@ -28,14 +28,31 @@
|
|||||||
|
|
||||||
#if GUF_PLATFORM_BITS <= 32
|
#if GUF_PLATFORM_BITS <= 32
|
||||||
#define GUF_HASH_32_BIT
|
#define GUF_HASH_32_BIT
|
||||||
|
#define GUF_RAND_32_BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
|
#if defined(__STDC_VERSION__)
|
||||||
#define GUF_STDC_AT_LEAST_C11
|
#if __STDC_VERSION__ >= 199901L
|
||||||
|
#define GUF_STDC_AT_LEAST_C99
|
||||||
|
#else
|
||||||
|
#error "libguf only supports C99 and above"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __STDC_VERSION__ >= 201112L
|
||||||
|
#define GUF_STDC_AT_LEAST_C11
|
||||||
|
#endif
|
||||||
|
#if __STDC_VERSION__ >= 201710L
|
||||||
|
#define GUF_STDC_AT_LEAST_C17
|
||||||
|
#endif
|
||||||
|
#if __STDC_VERSION__ >= 202311L
|
||||||
|
#define GUF_STDC_AT_LEAST_C23
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__cplusplus) && __cplusplus >= 201103L)
|
#if defined(__cplusplus)
|
||||||
#define GUF_STDCPP_AT_LEAST_CPP11
|
#if __cplusplus >= 201103L
|
||||||
|
#define GUF_STDCPP_AT_LEAST_CPP11
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -19,10 +19,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define GUF_HASH32_INIT UINT32_C(2166136261)
|
#define GUF_HASH32_INIT UINT32_C(2166136261)
|
||||||
#define GUF_HASH64_INIT UINT64_C(14695981039346656037)
|
#ifdef UINT64_MAX
|
||||||
|
#define GUF_HASH64_INIT UINT64_C(14695981039346656037)
|
||||||
|
#endif
|
||||||
|
|
||||||
GUF_HASH_KWRDS uint32_t guf_hash32(const void *data, ptrdiff_t num_bytes, uint32_t hash); // FNV-1a (32 bit)
|
GUF_HASH_KWRDS uint32_t guf_hash32(const void *data, ptrdiff_t num_bytes, uint32_t hash); // FNV-1a (32 bit)
|
||||||
GUF_HASH_KWRDS uint64_t guf_hash64(const void *data, ptrdiff_t num_bytes, uint64_t hash); // FNV-1a (64 bit)
|
#ifdef UINT64_MAX
|
||||||
|
GUF_HASH_KWRDS uint64_t guf_hash64(const void *data, ptrdiff_t num_bytes, uint64_t hash); // FNV-1a (64 bit)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef GUF_HASH_32_BIT
|
#ifdef GUF_HASH_32_BIT
|
||||||
typedef uint32_t guf_hash_size_t;
|
typedef uint32_t guf_hash_size_t;
|
||||||
@ -32,6 +36,9 @@ GUF_HASH_KWRDS uint64_t guf_hash64(const void *data, ptrdiff_t num_bytes, uint64
|
|||||||
return guf_hash32(data, num_bytes, hash);
|
return guf_hash32(data, num_bytes, hash);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
#ifndef UINT64_MAX
|
||||||
|
#error "guf_hash.h: Platform does not support uint64_t (define GUF_HASH_32_BIT to fix)"
|
||||||
|
#endif
|
||||||
typedef uint64_t guf_hash_size_t;
|
typedef uint64_t guf_hash_size_t;
|
||||||
#define GUF_HASH_INIT GUF_HASH64_INIT
|
#define GUF_HASH_INIT GUF_HASH64_INIT
|
||||||
#define GUF_HASH_MAX UINT64_MAX
|
#define GUF_HASH_MAX UINT64_MAX
|
||||||
@ -59,18 +66,20 @@ GUF_HASH_KWRDS uint32_t guf_hash32(const void *data, ptrdiff_t num_bytes, uint32
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUF_HASH_KWRDS uint64_t guf_hash64(const void *data, ptrdiff_t num_bytes, uint64_t hash)
|
#ifdef UINT64_MAX
|
||||||
{
|
GUF_HASH_KWRDS uint64_t guf_hash64(const void *data, ptrdiff_t num_bytes, uint64_t hash)
|
||||||
GUF_ASSERT_RELEASE(data);
|
{
|
||||||
GUF_ASSERT_RELEASE(num_bytes >= 0);
|
GUF_ASSERT_RELEASE(data);
|
||||||
const unsigned char *data_bytes = (const unsigned char*)data; // This does not break strict-aliasing rules I think...
|
GUF_ASSERT_RELEASE(num_bytes >= 0);
|
||||||
const uint64_t FNV_64_PRIME = UINT64_C(1099511628211);
|
const unsigned char *data_bytes = (const unsigned char*)data; // This does not break strict-aliasing rules I think...
|
||||||
for (ptrdiff_t i = 0; i < num_bytes; ++i) {
|
const uint64_t FNV_64_PRIME = UINT64_C(1099511628211);
|
||||||
hash ^= data_bytes[i];
|
for (ptrdiff_t i = 0; i < num_bytes; ++i) {
|
||||||
hash *= FNV_64_PRIME;
|
hash ^= data_bytes[i];
|
||||||
|
hash *= FNV_64_PRIME;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
}
|
}
|
||||||
return hash;
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
#undef GUF_HASH_IMPL
|
#undef GUF_HASH_IMPL
|
||||||
#undef GUF_HASH_IMPL_STATIC
|
#undef GUF_HASH_IMPL_STATIC
|
||||||
|
|||||||
@ -124,6 +124,17 @@ static inline bool guf_sub_is_overflow_i32(int32_t a, int32_t b)
|
|||||||
(b > 0 && a < INT32_MIN + b); // a - b underflow
|
(b > 0 && a < INT32_MIN + b); // a - b underflow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool guf_add_is_overflow_i64(int64_t a, int64_t b)
|
||||||
|
{
|
||||||
|
return (b > 0 && a > INT64_MAX - b) || // a + b overflow
|
||||||
|
(b < 0 && a < INT64_MIN - b); // a + b underflow
|
||||||
|
}
|
||||||
|
static inline bool guf_sub_is_overflow_i64(int64_t a, int64_t b)
|
||||||
|
{
|
||||||
|
return (b < 0 && a > INT64_MAX + b) || // a - b overflow
|
||||||
|
(b > 0 && a < INT64_MIN + b); // a - b underflow
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool guf_size_calc_safe(ptrdiff_t count, ptrdiff_t sizeof_elem, ptrdiff_t *result)
|
static inline bool guf_size_calc_safe(ptrdiff_t count, ptrdiff_t sizeof_elem, ptrdiff_t *result)
|
||||||
{
|
{
|
||||||
if (count < 0 || sizeof_elem <= 0) {
|
if (count < 0 || sizeof_elem <= 0) {
|
||||||
|
|||||||
838
src/guf_rand.h
838
src/guf_rand.h
File diff suppressed because it is too large
Load Diff
@ -4,19 +4,69 @@
|
|||||||
|
|
||||||
#ifndef GUF_UTILS_H
|
#ifndef GUF_UTILS_H
|
||||||
#define GUF_UTILS_H
|
#define GUF_UTILS_H
|
||||||
|
#include "guf_common.h"
|
||||||
#include "guf_assert.h"
|
#include "guf_assert.h"
|
||||||
|
|
||||||
static inline bool guf_platform_is_big_endian(void)
|
static inline void guf_platform_assert_endianness(void)
|
||||||
{
|
{
|
||||||
unsigned i = 1;
|
const unsigned i = 1;
|
||||||
const char *bytes = (const char*)&i;
|
const char *bytes = (const char*)&i;
|
||||||
return bytes[0] != 1;
|
const bool is_big_endian = bytes[0] != 1;
|
||||||
|
#if defined(GUF_PLATFORM_LITTLE_ENDIAN)
|
||||||
|
GUF_ASSERT_RELEASE(!is_big_endian)
|
||||||
|
#elif defined(GUF_PLATFORM_BIG_ENDIAN)
|
||||||
|
GUF_ASSERT_RELEASE(is_big_endian)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int guf_platform_native_word_bits(void)
|
static inline void guf_platform_assert_native_word_bits(void)
|
||||||
{
|
{
|
||||||
const int bits = sizeof(void*) * CHAR_BIT;
|
const int bits = sizeof(void*) * CHAR_BIT;
|
||||||
return bits;
|
GUF_ASSERT_RELEASE(GUF_PLATFORM_BITS == bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define GUF_DBG_STR "release"
|
||||||
|
#else
|
||||||
|
#define GUF_DBG_STR "debug"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GUF_STDC_AT_LEAST_C23)
|
||||||
|
#ifdef GUF_PLATFORM_LITTLE_ENDIAN
|
||||||
|
#define GUF_PLATFORM_STRING "C23 (or above) " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "little-endian " GUF_DBG_STR
|
||||||
|
#else
|
||||||
|
#define GUF_PLATFORM_STRING "C23 (or above) " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "big-endian " GUF_DBG_STR
|
||||||
|
#endif
|
||||||
|
#elif defined(GUF_STDC_AT_LEAST_C17)
|
||||||
|
#ifdef GUF_PLATFORM_LITTLE_ENDIAN
|
||||||
|
#define GUF_PLATFORM_STRING "C17 " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "little-endian " GUF_DBG_STR
|
||||||
|
#else
|
||||||
|
#define GUF_PLATFORM_STRING "C17 " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "big-endian " GUF_DBG_STR
|
||||||
|
#endif
|
||||||
|
#elif defined(GUF_STDC_AT_LEAST_C11)
|
||||||
|
#ifdef GUF_PLATFORM_LITTLE_ENDIAN
|
||||||
|
#define GUF_PLATFORM_STRING "C11 " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "little-endian " GUF_DBG_STR
|
||||||
|
#else
|
||||||
|
#define GUF_PLATFORM_STRING "C11 " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "big-endian " GUF_DBG_STR
|
||||||
|
#endif
|
||||||
|
#elif defined(GUF_STDC_AT_LEAST_C99)
|
||||||
|
#ifdef GUF_PLATFORM_LITTLE_ENDIAN
|
||||||
|
#define GUF_PLATFORM_STRING "C99 " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "little-endian " GUF_DBG_STR
|
||||||
|
#else
|
||||||
|
#define GUF_PLATFORM_STRING "C99 " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "big-endian " GUF_DBG_STR
|
||||||
|
#endif
|
||||||
|
#elif defined(GUF_STDCPP_AT_LEAST_CPP11)
|
||||||
|
#ifdef GUF_PLATFORM_LITTLE_ENDIAN
|
||||||
|
#define GUF_PLATFORM_STRING "C++11 (or above) " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "little-endian " GUF_DBG_STR
|
||||||
|
#else
|
||||||
|
#define GUF_PLATFORM_STRING "C++11 (or above) " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "big-endian " GUF_DBG_STR
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef GUF_PLATFORM_LITTLE_ENDIAN
|
||||||
|
#define GUF_PLATFORM_STRING "C?? " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "little-endian " GUF_DBG_STR
|
||||||
|
#else
|
||||||
|
#define GUF_PLATFORM_STRING "C?? " GUF_STRINGIFY(GUF_PLATFORM_BITS) "-bit " "big-endian " GUF_DBG_STR
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "guf_alloc_libc.h"
|
#include "guf_alloc_libc.h"
|
||||||
#include "guf_cstr.h"
|
#include "guf_cstr.h"
|
||||||
#include "guf_linalg.h"
|
#include "guf_linalg.h"
|
||||||
|
#include "guf_utils.h"
|
||||||
|
|
||||||
#define GUF_T float
|
#define GUF_T float
|
||||||
#define GUF_SORT_IMPL_STATIC
|
#define GUF_SORT_IMPL_STATIC
|
||||||
@ -46,13 +47,16 @@
|
|||||||
#include "guf_dbuf.h"
|
#include "guf_dbuf.h"
|
||||||
|
|
||||||
#define GUF_RAND_IMPL_STATIC
|
#define GUF_RAND_IMPL_STATIC
|
||||||
|
// #define GUF_RAND_32_BIT
|
||||||
#include "guf_rand.h"
|
#include "guf_rand.h"
|
||||||
|
|
||||||
#include "impls/dict_impl.h"
|
#include "impls/dict_impl.h"
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
printf("libguf test: compiled with C %ld\n", __STDC_VERSION__);
|
printf("libguf example: " GUF_PLATFORM_STRING "\n");
|
||||||
|
guf_platform_assert_endianness();
|
||||||
|
guf_platform_assert_native_word_bits();
|
||||||
|
|
||||||
guf_allocator test_allocator = guf_allocator_libc;
|
guf_allocator test_allocator = guf_allocator_libc;
|
||||||
guf_libc_alloc_ctx test_allocator_ctx = {.alloc_type_id = 0, .thread_id = 0, .zero_init = true};
|
guf_libc_alloc_ctx test_allocator_ctx = {.alloc_type_id = 0, .thread_id = 0, .zero_init = true};
|
||||||
@ -206,7 +210,7 @@ int main(void)
|
|||||||
dbuf_int_free(&integers, NULL);
|
dbuf_int_free(&integers, NULL);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
guf_randstate rng;
|
guf_randstate rng;
|
||||||
guf_randstate_init(&rng, time(NULL));
|
guf_randstate_init(&rng, (guf_rand_seed_t)time(NULL));
|
||||||
int heads = 0, tails = 0;
|
int heads = 0, tails = 0;
|
||||||
int throws = 10;
|
int throws = 10;
|
||||||
for (i = 0; i < throws; ++i) {
|
for (i = 0; i < throws; ++i) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user