C API: Added individual primitive types `rng_next_*()`

Defined in rngxx.h header as `inline static __gnu_inline` (force inline). To compile into consumer libraries as ONLY inline (no symbol emitted) `inline extern __gnu_inline`, define the macro `_RNGXX_INLINE_ONLY` (If inlining is disabled by compiler flag (e.g. `-O0`), this will cause linker failures.)

Fortune for rngxx's current commit: Curse − 凶
iter
Avril 3 years ago
parent 12f5e7dd97
commit ebc16f5638

@ -4,7 +4,7 @@ PROJECT=rngxx
AUTHOR=Avril (Flanchan) <flanchan@cumallover.me> AUTHOR=Avril (Flanchan) <flanchan@cumallover.me>
VERSION_MAJOR=0 VERSION_MAJOR=0
VERSION_MINOR=1 VERSION_MINOR=2
VERSION=$(VERSION_MAJOR).$(VERSION_MINOR) VERSION=$(VERSION_MAJOR).$(VERSION_MINOR)
ifeq ($(PREFIX),) ifeq ($(PREFIX),)

@ -80,6 +80,46 @@ void* rng_next_tyb(rng_t* engine, void* restrict output, enum rng_next_type ty,
rng_t* rng_new(enum rng_kind kind, const u64 seed[static restrict 1]); rng_t* rng_new(enum rng_kind kind, const u64 seed[static restrict 1]);
void rng_free(rng_t* rng); 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; \
}
#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;
}
#undef NEXT_TYPED_INT
#undef _NEXT_TYPED
#undef _NEXT_TYPED_
#undef _rng__always_inline
// -- // -- // -- // --
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

@ -228,8 +228,10 @@ DEF
template<> inline T Random::next< T >(T min, T max) { return next_ ## T(min, max); } \ template<> inline T Random::next< T >(T min, T max) { return next_ ## T(min, max); } \
template<> inline T Random::next< T >(T max) { return next_ ## T(max); } template<> inline T Random::next< T >(T max) { return next_ ## T(max); }
template<> inline bool Random::next<bool>() { return next_bool(); } template<> inline bool Random::next<bool>() { return next_bool(); }
template<> inline f64 Random::next<f64>() { return next_f64(); } //template<> inline f64 Random::next<f64>() { return next_f64(); }
template<> inline f32 Random::next<f32>() { return next_f32(); } //template<> inline f32 Random::next<f32>() { return next_f32(); }
DEFT(f32)
DEFT(f64)
DEF DEF
#undef DEF #undef DEF
#undef DEFTT #undef DEFTT

@ -15,10 +15,13 @@ namespace bridge _export(internal)
template<typename T> template<typename T>
inline T next_typed(Random& engine, const void* minp = nullptr, const void* maxp = nullptr) inline T next_typed(Random& engine, const void* minp = nullptr, const void* maxp = nullptr)
{ {
if constexpr(!is_same_any<T, f32, f64, bool>()) { if constexpr(!is_same_any<T, bool>()) {
if(minp && maxp) return engine.next(*reinterpret_cast<const T*>(minp), *reinterpret_cast<const T*>(maxp)); if(minp && maxp) return engine.next(*reinterpret_cast<const T*>(minp), *reinterpret_cast<const T*>(maxp));
else if(maxp) return engine.next(*reinterpret_cast<const T*>(maxp)); else if(maxp) return engine.next(*reinterpret_cast<const T*>(maxp));
else if(minp) return engine.next(*reinterpret_cast<const T*>(minp), engine.max_for<T>()); else {
if constexpr(!is_same_any<T, f32, f64>())
if(minp)return engine.next(*reinterpret_cast<const T*>(minp), engine.max_for<T>());
}
} }
return engine.next<T>(); return engine.next<T>();
} }
@ -115,10 +118,10 @@ extern "C" {
INTTY(64); INTTY(64);
#undef INTTY #undef INTTY
case RNG_TY_F32: case RNG_TY_F32:
bridge::next_typed_into<f32>(*engine, output); bridge::next_typed_into<f32>(*engine, output, opt->bound.range.pmin, opt->bound.range.pmax);
break; break;
case RNG_TY_F64: case RNG_TY_F64:
bridge::next_typed_into<f64>(*engine, output); bridge::next_typed_into<f64>(*engine, output, opt->bound.range.pmin, opt->bound.range.pmax);
break; break;
case RNG_TY_BOOL: case RNG_TY_BOOL:
*reinterpret_cast<rng_bool_t*>(output) = bridge::next_typed<bool>(*engine, output) ? 1 : 0; *reinterpret_cast<rng_bool_t*>(output) = bridge::next_typed<bool>(*engine, output) ? 1 : 0;

@ -1,6 +1,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#define _RNGXX_INLINE_ONLY
#include <rngxx.h> #include <rngxx.h>
static int next(rng_t* rng, const int* min, const int* max) static int next(rng_t* rng, const int* min, const int* max)
@ -15,8 +18,11 @@ static int next(rng_t* rng, const int* min, const int* max)
#define TREF(x) ( (const __typeof(x)[]){ (x) } ) #define TREF(x) ( (const __typeof(x)[]){ (x) } )
int main() int main()
{ {
rng_t* engine = rng_new(RNG_KIND_CRAND, (const u64[]){ 1000 }); rng_t* engine = rng_new(RNG_KIND_CRAND, (const u64[]){ time(NULL) });
printf("%d %d %d\n", next(engine, NULL, TREF(100)), next(engine, TREF(10), TREF(20)), next(engine, NULL, NULL)); printf("%d %d %d\n", next(engine, NULL, TREF(100)), next(engine, TREF(10), TREF(20)), next(engine, NULL, NULL));
printf("%ld\n", rng_next_i64(engine, NULL, NULL));
printf("%lf\n", rng_next_f64(engine, TREF(1.0), TREF(100.0)));
printf("%d\n", rng_next_bool(engine));
rng_free(engine); rng_free(engine);
return 0; return 0;
} }

Loading…
Cancel
Save