|
|
|
@ -29,11 +29,27 @@ namespace bridge _export(internal)
|
|
|
|
|
return engine.next<T>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline void rep_ptr(void* vptr, size_t n, auto lambda)
|
|
|
|
|
{
|
|
|
|
|
T* ptr = reinterpret_cast<T*>(vptr);
|
|
|
|
|
if(!n) lambda(ptr);
|
|
|
|
|
else while( n --> 0 ) lambda(ptr++);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline void next_typed_into(Random& engine, void* restrict output, const void* minp = nullptr, const void* maxp = nullptr)
|
|
|
|
|
{
|
|
|
|
|
*reinterpret_cast<T* restrict>(output) = next_typed<T>(engine, minp, maxp);
|
|
|
|
|
}
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline void next_typed_into_n(Random& engine, void* restrict output, size_t rep = 0, const void* minp = nullptr, const void* maxp = nullptr)
|
|
|
|
|
{
|
|
|
|
|
if(!rep) return next_typed_into<T>(engine, output, minp, maxp);
|
|
|
|
|
T* restrict ro = reinterpret_cast<T*>(output);
|
|
|
|
|
while( rep --> 0 )
|
|
|
|
|
next_typed_into<T>(engine, reinterpret_cast<void*>(ro++), minp, maxp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void nblob(Random& engine, unsigned char* restrict output, size_t es, size_t l)
|
|
|
|
|
{
|
|
|
|
@ -47,7 +63,7 @@ namespace bridge _export(internal)
|
|
|
|
|
{
|
|
|
|
|
switch(ty)
|
|
|
|
|
{
|
|
|
|
|
case RNG_TY_BOOL: return alignof(bool);
|
|
|
|
|
case RNG_TY_BOOL: return alignof(rng_bool_t);
|
|
|
|
|
|
|
|
|
|
case RNG_TY_INT8: return alignof(i8);
|
|
|
|
|
case RNG_TY_INT16: return alignof(i16);
|
|
|
|
@ -64,7 +80,7 @@ namespace bridge _export(internal)
|
|
|
|
|
{
|
|
|
|
|
switch(ty)
|
|
|
|
|
{
|
|
|
|
|
case RNG_TY_BOOL: return sizeof(bool);
|
|
|
|
|
case RNG_TY_BOOL: return sizeof(rng_bool_t);
|
|
|
|
|
|
|
|
|
|
case RNG_TY_INT8: return sizeof(i8);
|
|
|
|
|
case RNG_TY_INT16: return sizeof(i16);
|
|
|
|
@ -81,11 +97,14 @@ namespace bridge _export(internal)
|
|
|
|
|
constexpr inline bool ty_signed(rng_next_flag f) { return ! (f & RNG_TYQ_UNSIGNED); }
|
|
|
|
|
constexpr inline bool ty_signed(const rng_next_tyq& qt) { return ty_signed(qt.mod); }
|
|
|
|
|
|
|
|
|
|
constexpr inline bool ty_hasflag(rng_next_flag hay, rng_next_flag nee) { return !!(hay & nee); }
|
|
|
|
|
constexpr inline bool ty_hasflag(const rng_next_tyq& q, rng_next_flag nee) { return ty_hasflag(q.mod, nee); }
|
|
|
|
|
|
|
|
|
|
template<typename S, typename U>
|
|
|
|
|
inline auto next_fun_of(const rng_next_tyq& ty)
|
|
|
|
|
{
|
|
|
|
|
if(ty_signed(ty)) return &next_typed_into<S>;
|
|
|
|
|
else return &next_typed_into<U>;
|
|
|
|
|
if(ty_signed(ty)) return &next_typed_into_n<S>; //ty.hasflag(ty, RNG_TYQ_ARRAY) ? &next_typed_into_n<S> : &next_typed_into<S>;
|
|
|
|
|
else return &next_typed_into_n<U>; //ty.hasflag(ty, RNG_TYQ_ARRAY) ? &next_typed_into_n<U> : &next_typed_into<U>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto dc_lookup(const char* name)
|
|
|
|
@ -126,25 +145,30 @@ extern "C" {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const size_t array = bridge::ty_hasflag(opt->ty, RNG_TYQ_ARRAY)
|
|
|
|
|
? static_cast<size_t>(opt->ex.array_size)
|
|
|
|
|
: 0;
|
|
|
|
|
switch(opt->ty.type)
|
|
|
|
|
{
|
|
|
|
|
case RNG_TY_BLOB: bridge::nblob(*engine, reinterpret_cast<unsigned char*>(output), opt->bound.len); break;
|
|
|
|
|
|
|
|
|
|
#define INTTY(bits) case RNG_TY_INT ## bits: \
|
|
|
|
|
bridge::next_fun_of<i ## bits, u ## bits>(opt->ty)(*engine, output, opt->bound.range.pmin, opt->bound.range.pmax); break
|
|
|
|
|
bridge::next_fun_of<i ## bits, u ## bits>(opt->ty)(*engine, output, array, opt->bound.range.pmin, opt->bound.range.pmax); break
|
|
|
|
|
INTTY(8);
|
|
|
|
|
INTTY(16);
|
|
|
|
|
INTTY(32);
|
|
|
|
|
INTTY(64);
|
|
|
|
|
#undef INTTY
|
|
|
|
|
case RNG_TY_F32:
|
|
|
|
|
bridge::next_typed_into<f32>(*engine, output, opt->bound.range.pmin, opt->bound.range.pmax);
|
|
|
|
|
bridge::next_typed_into_n<f32>(*engine, output, array, opt->bound.range.pmin, opt->bound.range.pmax);
|
|
|
|
|
break;
|
|
|
|
|
case RNG_TY_F64:
|
|
|
|
|
bridge::next_typed_into<f64>(*engine, output, opt->bound.range.pmin, opt->bound.range.pmax);
|
|
|
|
|
bridge::next_typed_into_n<f64>(*engine, output, array, opt->bound.range.pmin, opt->bound.range.pmax);
|
|
|
|
|
break;
|
|
|
|
|
case RNG_TY_BOOL:
|
|
|
|
|
*reinterpret_cast<rng_bool_t*>(output) = bridge::next_typed<bool>(*engine, output) ? 1 : 0;
|
|
|
|
|
bridge::rep_ptr<rng_bool_t>(output, array, [&](rng_bool_t* restrict output) {
|
|
|
|
|
*output = bridge::next_typed<bool>(*engine) ? 1 : 0;
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
default: return 0;
|
|
|
|
|
}
|
|
|
|
|