You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
4.8 KiB
168 lines
4.8 KiB
// C api for rngxx
|
|
#ifndef _RNGXX_H
|
|
#define _RNGXX_H
|
|
|
|
#ifndef _RNGXX_IMPL
|
|
#define _RNGXX_COMMON_MINIMAL
|
|
#endif
|
|
#include "rngxx/internal/common.h"
|
|
#ifndef _RNGXX_IMPL
|
|
#undef _RNGXX_COMMON_MINIMAL
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
#ifndef _RNGXX_IMPL_ONLY_TYPES
|
|
#warning "C++ compilers might not like this header file. Please use the C++ interface for C++ TUs"
|
|
#endif
|
|
extern "C" {
|
|
#endif
|
|
|
|
// -- C API types -- (C++ compat)
|
|
typedef struct Random rng_t;
|
|
|
|
enum rng_kind {
|
|
RNG_KIND_CRAND,
|
|
};
|
|
|
|
enum rng_next_flag {
|
|
RNG_TYQ_SIGNED = 0, // Binary with `unsigned`.
|
|
RNG_TYQ_UNSIGNED = 1 << 0,
|
|
|
|
RNG_TYQ_CHAOS = 1 << 1,
|
|
RNG_TYQ_ARRAY = 1 << 2,
|
|
}; // 3 bits
|
|
|
|
typedef int rng_bool_t;
|
|
|
|
enum rng_next_type {
|
|
RNG_TY_BLOB = 0,
|
|
|
|
RNG_TY_BOOL, // Expects type `rng_bool_t`.
|
|
|
|
RNG_TY_INT8,
|
|
RNG_TY_INT16,
|
|
RNG_TY_INT32,
|
|
RNG_TY_INT64,
|
|
|
|
RNG_TY_F32,
|
|
RNG_TY_F64,
|
|
}; // 4 bits
|
|
|
|
struct rng_next_opt {
|
|
union {
|
|
// Bounded types
|
|
struct {
|
|
const void* restrict pmin;
|
|
const void* restrict pmax;
|
|
} range;
|
|
// Blob types
|
|
size_t len;
|
|
} bound;
|
|
|
|
struct {
|
|
enum rng_next_type type : 4;
|
|
enum rng_next_flag mod : 3;
|
|
uint8_t _unused0 : 1;
|
|
//first byte
|
|
|
|
uint32_t _padding : 24;
|
|
} ty; // 32 bits :/
|
|
union {
|
|
uint32_t array_size;
|
|
} ex; // 32 bits. fills hole
|
|
};
|
|
|
|
typedef __typeof( ((struct rng_next_opt*)NULL)->ty ) rng_next_tyq; // Qualified type
|
|
|
|
typedef rng_t* (*rng_ctor_fn)(const void*);
|
|
|
|
typedef struct rng_dyn_ctor* rng_dyn_ctor_ref;
|
|
|
|
// -- // --
|
|
#ifndef _RNGXX_IMPL_ONLY_TYPES
|
|
|
|
_Static_assert(sizeof(rng_next_tyq) == sizeof(uint32_t));
|
|
_Static_assert(sizeof( ((struct rng_next_opt*)NULL)->ex ) == sizeof(uint32_t));
|
|
|
|
// -- C API functions -- (C++ NO compat)
|
|
|
|
int rng_raw(rng_t* engine, void* restrict output, struct rng_next_opt opt);
|
|
void rng_next_bin(rng_t* engine, unsigned char* restrict output, size_t n);
|
|
|
|
void* rng_next_ty(rng_t* engine, void* restrict output, enum rng_next_type ty, enum rng_next_flag flags);
|
|
void* rng_next_tya(rng_t* engine, void* restrict output, enum rng_next_type ty, enum rng_next_flag flags, uint32_t sz);
|
|
void* rng_next_tyab(rng_t* engine, void* restrict output, enum rng_next_type ty, enum rng_next_flag flags, uint32_t sz, const void* pmin, const void* pmax);
|
|
void* rng_next_tyb(rng_t* engine, void* restrict output, enum rng_next_type ty, enum rng_next_flag flags, const void* pmin, const void* pmax);
|
|
|
|
rng_dyn_ctor_ref rng_ctor_ref(const char* name);
|
|
rng_ctor_fn rng_ctor(const char* name) __attribute__((deprecated("many dynamic ctors will have state that cannot be expressed through a raw function pointer, and so this method will not work for them. use `rng_ctor_ref` and `rng_ctor_call` instead where possible, unless you know that the dynamic ctor is a bare function pointer."))); // Get a dynamic ctor that is a raw funciton pointer. If the ctor for this name is not a raw function pointer (if it has state), then NULL is returned.
|
|
rng_t* rng_ctor_call(rng_dyn_ctor_ref ctor, const void* seed);
|
|
|
|
rng_t* rng_new_named(const char* name, const void* seed);
|
|
rng_t* rng_new(enum rng_kind kind, const u64 seed[static restrict 1]);
|
|
void rng_free(rng_t* rng);
|
|
|
|
#ifdef _RNGXX_INLINE_ONLY
|
|
#define _rng__always_inline __attribute__((gnu_inline)) inline extern
|
|
#else
|
|
#define _rng__always_inline __attribute__((gnu_inline)) inline static
|
|
#endif
|
|
|
|
#define _NEXT_TYPED_(name, T, N, S) \
|
|
_rng__always_inline T rng_next_ ## name (rng_t* engine, const T* min, const T* max) \
|
|
{ \
|
|
T output; \
|
|
rng_next_tyb(engine, &output, RNG_TY_ ## N, RNG_TYQ_ ## S, min, max); \
|
|
return output; \
|
|
} \
|
|
_rng__always_inline T* rng_nexta_ ## name(uint32_t len; rng_t* engine, T output[restrict len], uint32_t len, const T* min, const T* max) \
|
|
{ \
|
|
return rng_next_tyab(engine, output, RNG_TY_ ## N, RNG_TYQ_ ## S, len, min, max); \
|
|
} \
|
|
_rng__always_inline T* rng_nextam_ ## name(rng_t* engine, uint32_t len, const T* min, const T* max) \
|
|
{ \
|
|
return rng_next_tyab(engine, NULL, RNG_TY_ ## N, RNG_TYQ_ ## S, len, min, max); \
|
|
}
|
|
|
|
#define _NEXT_TYPED(T, N, S) _NEXT_TYPED_(T, T, N, S)
|
|
|
|
#define NEXT_TYPED_INT(n) _NEXT_TYPED(i ## n, INT ## n, SIGNED) \
|
|
_NEXT_TYPED(u ## n, INT ## n, UNSIGNED)
|
|
|
|
NEXT_TYPED_INT(8)
|
|
NEXT_TYPED_INT(16)
|
|
NEXT_TYPED_INT(32)
|
|
NEXT_TYPED_INT(64)
|
|
|
|
_NEXT_TYPED(f32, F32, SIGNED)
|
|
_NEXT_TYPED(f64, F64, SIGNED)
|
|
|
|
_rng__always_inline rng_bool_t rng_next_bool(rng_t* engine)
|
|
{
|
|
rng_bool_t output;
|
|
rng_next_tyb(engine, &output, RNG_TY_BOOL, 0, NULL, NULL);
|
|
return output & 1;
|
|
}
|
|
_rng__always_inline rng_bool_t* rng_nexta_bool(uint32_t len; rng_t* engine, rng_bool_t output[restrict len], uint32_t len)
|
|
{
|
|
return rng_next_tyab(engine, output, RNG_TY_BOOL, 0, len, NULL, NULL);
|
|
}
|
|
_rng__always_inline rng_bool_t* rng_nextam_bool(rng_t* engine, uint32_t len)
|
|
{
|
|
return rng_next_tyab(engine, NULL, RNG_TY_BOOL, 0, len, NULL, NULL);
|
|
}
|
|
|
|
#undef NEXT_TYPED_INT
|
|
#undef _NEXT_TYPED
|
|
#undef _NEXT_TYPED_
|
|
|
|
#undef _rng__always_inline
|
|
|
|
// -- // --
|
|
#endif
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _RNGXX_H */
|