@ -5,29 +5,88 @@
# include "capi-bridge.h"
template < typename T , typename . . . Args >
static inline consteval bool is_same_any ( ) {
return ( std : : is_same_v < T , Args > | | . . . ) ;
}
namespace bridge _export ( internal )
{
void nblob ( Random & restrict engine , unsigned char * restrict output , size_t es , size_t l )
template < typename T >
inline T next_typed ( Random & engine , const void * minp = nullptr , const void * maxp = nullptr )
{
if constexpr ( ! is_same_any < T , f32 , f64 , bool > ( ) ) {
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 ( minp ) return engine . next ( * reinterpret_cast < const T * > ( minp ) , engine . max_for < T > ( ) ) ;
}
return engine . next < T > ( ) ;
}
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 ) ;
}
inline void nblob ( Random & engine , unsigned char * restrict output , size_t es , size_t l )
{
size_t len = es * l ; // full length (bytes)
engine . next_bytes ( output , len ) ;
}
inline void nblob ( Random & restrict engine , unsigned char * restrict output , size_t len ) { nblob ( engine , output , 1 , len ) ; }
inline void nblob ( Random & engine , unsigned char * restrict output , size_t len ) { nblob ( engine , output , 1 , len ) ; }
constexpr inline size_t ty_alignof ( rng_next_type ty )
{
switch ( ty )
{
case RNG_TY_BOOL : return alignof ( bool ) ;
case RNG_TY_INT8 : return alignof ( i8 ) ;
case RNG_TY_INT16 : return alignof ( i16 ) ;
case RNG_TY_INT32 : return alignof ( i32 ) ;
case RNG_TY_INT64 : return alignof ( i64 ) ;
case RNG_TY_F32 : return alignof ( f32 ) ;
case RNG_TY_F64 : return alignof ( f64 ) ;
case RNG_TY_BLOB : return 0 ;
default : return 0 ;
}
}
constexpr inline size_t ty_sizeof ( rng_next_type ty )
{
//TODO:
switch ( ty )
{
case RNG_TY_BOOL : return sizeof ( bool ) ;
case RNG_TY_INT8 : return sizeof ( i8 ) ;
case RNG_TY_INT16 : return sizeof ( i16 ) ;
case RNG_TY_INT32 : return sizeof ( i32 ) ;
case RNG_TY_INT64 : return sizeof ( i64 ) ;
case RNG_TY_F32 : return sizeof ( f32 ) ;
case RNG_TY_F64 : return sizeof ( f64 ) ;
case RNG_TY_BLOB : return 0 ;
default : return 0 ;
}
}
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 ) ; }
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 > ;
}
}
extern " C " {
// Internal bridge members
_export ( internal )
rng_t * RNG_IMPL ( mkdriver ) ( rng_kind kind , u64 * restrict seed )
rng_t * RNG_IMPL ( mkdriver ) ( rng_kind kind , const u64 * restrict seed )
{
switch ( kind )
{
@ -37,22 +96,47 @@ extern "C" {
}
}
_export ( internal )
int RNG_IMPL ( mnext ) ( rng_t * restrict engine , void * restrict output , const rng_next_opt * restrict opt )
int RNG_IMPL ( mnext ) ( rng_t * engine , void * restrict output , const rng_next_opt * restrict opt )
{
if ( opt - > ty . mod & RNG_TYQ_CHAOS ) {
bridge : : nblob ( * engine , reinterpret_cast < unsigned char * > ( output ) , bridge : : ty_sizeof ( opt - > ty . type ) , opt - > bound . len );
bridge : : nblob ( * engine , reinterpret_cast < unsigned char * > ( output ) , bridge : : ty_sizeof ( opt - > ty . type ) );
return 1 ;
}
switch ( opt - > ty . type )
{
case RNG_TY_BLOB : bridge : : nblob ( * engine , reinterpret_cast < unsigned char * > ( output ) , opt - > bound . len ) ; break ;
//TODO: Rest of types
# 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
INTTY ( 8 ) ;
INTTY ( 16 ) ;
INTTY ( 32 ) ;
INTTY ( 64 ) ;
# undef INTTY
case RNG_TY_F32 :
bridge : : next_typed_into < f32 > ( * engine , output ) ;
break ;
case RNG_TY_F64 :
bridge : : next_typed_into < f64 > ( * engine , output ) ;
break ;
case RNG_TY_BOOL :
* reinterpret_cast < rng_bool_t * > ( output ) = bridge : : next_typed < bool > ( * engine , output ) ? 1 : 0 ;
break ;
default : return 0 ;
}
return 1 ;
}
_export ( internal )
int RNG_IMPL ( m_allocsz_for ) ( enum rng_next_type ty , size_t * restrict size , size_t * restrict align )
{
int ok = 0 ;
if ( size ) ok | = ( ( * size = bridge : : ty_sizeof ( ty ) ) > 0 ) ? 1 : 0 ;
if ( align ) ok | = ( ( * align = bridge : : ty_alignof ( ty ) ) > 0 ) ? 2 : 0 ;
return ok ;
}
// Direct C interface members
void rng_free ( rng_t * rng )
{