mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 04:07:58 +00:00
Extract rb_random_interface_t alongside rb_random_t as well
This commit is contained in:
parent
68cd46353c
commit
44e762a99c
Notes:
git
2025-12-28 18:41:56 +00:00
107
random.c
107
random.c
@ -315,31 +315,24 @@ get_rnd_mt(VALUE obj)
|
||||
}
|
||||
|
||||
static rb_random_t *
|
||||
try_get_rnd(VALUE obj)
|
||||
try_get_rnd(VALUE obj, const rb_random_interface_t **rng_p)
|
||||
{
|
||||
if (obj == rb_cRandom) {
|
||||
*rng_p = &random_mt_if;
|
||||
return default_rand_start();
|
||||
}
|
||||
if (!rb_typeddata_is_kind_of(obj, &rb_random_data_type)) return NULL;
|
||||
if (RTYPEDDATA_TYPE(obj) == &random_mt_type)
|
||||
return rand_start(DATA_PTR(obj), obj);
|
||||
rb_random_t *rnd = DATA_PTR(obj);
|
||||
const struct rb_data_type_struct *type = RTYPEDDATA_TYPE(obj);
|
||||
*rng_p = type->data;
|
||||
void *rnd = DATA_PTR(obj);
|
||||
if (!rnd) {
|
||||
rb_raise(rb_eArgError, "uninitialized random: %s",
|
||||
RTYPEDDATA_TYPE(obj)->wrap_struct_name);
|
||||
}
|
||||
if (type == &random_mt_type) rnd = rand_start(rnd, obj);
|
||||
return rnd;
|
||||
}
|
||||
|
||||
static const rb_random_interface_t *
|
||||
try_rand_if(VALUE obj, rb_random_t *rnd)
|
||||
{
|
||||
if (rnd == &default_rand()->base) {
|
||||
return &random_mt_if;
|
||||
}
|
||||
return rb_rand_if(obj);
|
||||
}
|
||||
|
||||
/* :nodoc: */
|
||||
void
|
||||
rb_random_base_init(rb_random_t *rnd)
|
||||
@ -412,8 +405,8 @@ rand_init(const rb_random_interface_t *rng, rb_random_t *rnd, VALUE seed)
|
||||
static VALUE
|
||||
random_init(int argc, VALUE *argv, VALUE obj)
|
||||
{
|
||||
rb_random_t *rnd = try_get_rnd(obj);
|
||||
const rb_random_interface_t *rng = rb_rand_if(obj);
|
||||
const rb_random_interface_t *rng;
|
||||
rb_random_t *rnd = try_get_rnd(obj, &rng);
|
||||
|
||||
if (!rng) {
|
||||
rb_raise(rb_eTypeError, "undefined random interface: %s",
|
||||
@ -1130,17 +1123,18 @@ random_int32(const rb_random_interface_t *rng, rb_random_t *rnd)
|
||||
unsigned int
|
||||
rb_random_int32(VALUE obj)
|
||||
{
|
||||
rb_random_t *rnd = try_get_rnd(obj);
|
||||
const rb_random_interface_t *rng;
|
||||
rb_random_t *rnd = try_get_rnd(obj, &rng);
|
||||
if (!rnd) {
|
||||
uint32_t x;
|
||||
obj_random_bytes(obj, &x, sizeof(x));
|
||||
return (unsigned int)x;
|
||||
}
|
||||
return random_int32(try_rand_if(obj, rnd), rnd);
|
||||
return random_int32(rng, rnd);
|
||||
}
|
||||
|
||||
static double
|
||||
random_real(VALUE obj, rb_random_t *rnd, int excl)
|
||||
random_real(VALUE obj, const rb_random_interface_t *rng, rb_random_t *rnd, int excl)
|
||||
{
|
||||
uint32_t a, b;
|
||||
|
||||
@ -1151,7 +1145,6 @@ random_real(VALUE obj, rb_random_t *rnd, int excl)
|
||||
b = x[1];
|
||||
}
|
||||
else {
|
||||
const rb_random_interface_t *rng = try_rand_if(obj, rnd);
|
||||
if (rng->get_real) return rng->get_real(rnd, excl);
|
||||
a = random_int32(rng, rnd);
|
||||
b = random_int32(rng, rnd);
|
||||
@ -1173,7 +1166,8 @@ rb_int_pair_to_real(uint32_t a, uint32_t b, int excl)
|
||||
double
|
||||
rb_random_real(VALUE obj)
|
||||
{
|
||||
rb_random_t *rnd = try_get_rnd(obj);
|
||||
const rb_random_interface_t *rng;
|
||||
rb_random_t *rnd = try_get_rnd(obj, &rng);
|
||||
if (!rnd) {
|
||||
VALUE v = rb_funcallv(obj, id_rand, 0, 0);
|
||||
double d = NUM2DBL(v);
|
||||
@ -1185,7 +1179,7 @@ rb_random_real(VALUE obj)
|
||||
}
|
||||
return d;
|
||||
}
|
||||
return random_real(obj, rnd, TRUE);
|
||||
return random_real(obj, rng, rnd, TRUE);
|
||||
}
|
||||
|
||||
static inline VALUE
|
||||
@ -1202,7 +1196,7 @@ ulong_to_num_plus_1(unsigned long n)
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
random_ulong_limited(VALUE obj, rb_random_t *rnd, unsigned long limit)
|
||||
random_ulong_limited(VALUE obj, const rb_random_interface_t *rng, rb_random_t *rnd, unsigned long limit)
|
||||
{
|
||||
if (!limit) return 0;
|
||||
if (!rnd) {
|
||||
@ -1227,13 +1221,14 @@ random_ulong_limited(VALUE obj, rb_random_t *rnd, unsigned long limit)
|
||||
} while (limit < val);
|
||||
return val;
|
||||
}
|
||||
return limited_rand(try_rand_if(obj, rnd), rnd, limit);
|
||||
return limited_rand(rng, rnd, limit);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
rb_random_ulong_limited(VALUE obj, unsigned long limit)
|
||||
{
|
||||
rb_random_t *rnd = try_get_rnd(obj);
|
||||
const rb_random_interface_t *rng;
|
||||
rb_random_t *rnd = try_get_rnd(obj, &rng);
|
||||
if (!rnd) {
|
||||
VALUE lim = ulong_to_num_plus_1(limit);
|
||||
VALUE v = rb_to_int(rb_funcallv_public(obj, id_rand, 1, &lim));
|
||||
@ -1246,11 +1241,11 @@ rb_random_ulong_limited(VALUE obj, unsigned long limit)
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return limited_rand(try_rand_if(obj, rnd), rnd, limit);
|
||||
return limited_rand(rng, rnd, limit);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
random_ulong_limited_big(VALUE obj, rb_random_t *rnd, VALUE vmax)
|
||||
random_ulong_limited_big(VALUE obj, const rb_random_interface_t *rng, rb_random_t *rnd, VALUE vmax)
|
||||
{
|
||||
if (!rnd) {
|
||||
VALUE v, vtmp;
|
||||
@ -1275,7 +1270,7 @@ random_ulong_limited_big(VALUE obj, rb_random_t *rnd, VALUE vmax)
|
||||
ALLOCV_END(vtmp);
|
||||
return v;
|
||||
}
|
||||
return limited_big_rand(try_rand_if(obj, rnd), rnd, vmax);
|
||||
return limited_big_rand(rng, rnd, vmax);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
@ -1301,8 +1296,9 @@ rand_bytes(const rb_random_interface_t *rng, rb_random_t *rnd, long n)
|
||||
static VALUE
|
||||
random_bytes(VALUE obj, VALUE len)
|
||||
{
|
||||
rb_random_t *rnd = try_get_rnd(obj);
|
||||
return rand_bytes(rb_rand_if(obj), rnd, NUM2LONG(rb_to_int(len)));
|
||||
const rb_random_interface_t *rng;
|
||||
rb_random_t *rnd = try_get_rnd(obj, &rng);
|
||||
return rand_bytes(rng, rnd, NUM2LONG(rb_to_int(len)));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1331,11 +1327,12 @@ rb_rand_bytes_int32(rb_random_get_int32_func *get_int32,
|
||||
VALUE
|
||||
rb_random_bytes(VALUE obj, long n)
|
||||
{
|
||||
rb_random_t *rnd = try_get_rnd(obj);
|
||||
const rb_random_interface_t *rng;
|
||||
rb_random_t *rnd = try_get_rnd(obj, &rng);
|
||||
if (!rnd) {
|
||||
return obj_random_bytes(obj, NULL, n);
|
||||
}
|
||||
return rand_bytes(try_rand_if(obj, rnd), rnd, n);
|
||||
return rand_bytes(rng, rnd, n);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1387,7 +1384,7 @@ range_values(VALUE vmax, VALUE *begp, VALUE *endp, int *exclp)
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rand_int(VALUE obj, rb_random_t *rnd, VALUE vmax, int restrictive)
|
||||
rand_int(VALUE obj, const rb_random_interface_t *rng, rb_random_t *rnd, VALUE vmax, int restrictive)
|
||||
{
|
||||
/* mt must be initialized */
|
||||
unsigned long r;
|
||||
@ -1399,7 +1396,7 @@ rand_int(VALUE obj, rb_random_t *rnd, VALUE vmax, int restrictive)
|
||||
if (restrictive) return Qnil;
|
||||
max = -max;
|
||||
}
|
||||
r = random_ulong_limited(obj, rnd, (unsigned long)max - 1);
|
||||
r = random_ulong_limited(obj, rng, rnd, (unsigned long)max - 1);
|
||||
return ULONG2NUM(r);
|
||||
}
|
||||
else {
|
||||
@ -1413,10 +1410,10 @@ rand_int(VALUE obj, rb_random_t *rnd, VALUE vmax, int restrictive)
|
||||
if (FIXNUM_P(vmax)) {
|
||||
long max = FIX2LONG(vmax);
|
||||
if (max == -1) return Qnil;
|
||||
r = random_ulong_limited(obj, rnd, max);
|
||||
r = random_ulong_limited(obj, rng, rnd, max);
|
||||
return LONG2NUM(r);
|
||||
}
|
||||
ret = random_ulong_limited_big(obj, rnd, vmax);
|
||||
ret = random_ulong_limited_big(obj, rng, rnd, vmax);
|
||||
RB_GC_GUARD(vmax);
|
||||
return ret;
|
||||
}
|
||||
@ -1460,7 +1457,7 @@ float_value(VALUE v)
|
||||
}
|
||||
|
||||
static inline VALUE
|
||||
rand_range(VALUE obj, rb_random_t* rnd, VALUE range)
|
||||
rand_range(VALUE obj, const rb_random_interface_t *rng, rb_random_t* rnd, VALUE range)
|
||||
{
|
||||
VALUE beg = Qundef, end = Qundef, vmax, v;
|
||||
int excl = 0;
|
||||
@ -1475,7 +1472,7 @@ rand_range(VALUE obj, rb_random_t* rnd, VALUE range)
|
||||
fixnum:
|
||||
if (FIXNUM_P(vmax)) {
|
||||
if ((max = FIX2LONG(vmax) - excl) >= 0) {
|
||||
unsigned long r = random_ulong_limited(obj, rnd, (unsigned long)max);
|
||||
unsigned long r = random_ulong_limited(obj, rng, rnd, (unsigned long)max);
|
||||
v = ULONG2NUM(r);
|
||||
}
|
||||
}
|
||||
@ -1485,7 +1482,7 @@ rand_range(VALUE obj, rb_random_t* rnd, VALUE range)
|
||||
excl = 0;
|
||||
goto fixnum;
|
||||
}
|
||||
v = random_ulong_limited_big(obj, rnd, vmax);
|
||||
v = random_ulong_limited_big(obj, rng, rnd, vmax);
|
||||
}
|
||||
}
|
||||
else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
|
||||
@ -1503,7 +1500,7 @@ rand_range(VALUE obj, rb_random_t* rnd, VALUE range)
|
||||
}
|
||||
v = Qnil;
|
||||
if (max > 0.0) {
|
||||
r = random_real(obj, rnd, excl);
|
||||
r = random_real(obj, rng, rnd, excl);
|
||||
if (scale > 1) {
|
||||
return rb_float_new(+(+(+(r - 0.5) * max) * scale) + mid);
|
||||
}
|
||||
@ -1536,7 +1533,7 @@ rand_range(VALUE obj, rb_random_t* rnd, VALUE range)
|
||||
return v;
|
||||
}
|
||||
|
||||
static VALUE rand_random(int argc, VALUE *argv, VALUE obj, rb_random_t *rnd);
|
||||
static VALUE rand_random(int argc, VALUE *argv, VALUE obj, const rb_random_interface_t *rng, rb_random_t *rnd);
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
@ -1573,24 +1570,26 @@ static VALUE rand_random(int argc, VALUE *argv, VALUE obj, rb_random_t *rnd);
|
||||
static VALUE
|
||||
random_rand(int argc, VALUE *argv, VALUE obj)
|
||||
{
|
||||
VALUE v = rand_random(argc, argv, obj, try_get_rnd(obj));
|
||||
const rb_random_interface_t *rng;
|
||||
rb_random_t *rnd = try_get_rnd(obj, &rng);
|
||||
VALUE v = rand_random(argc, argv, obj, rng, rnd);
|
||||
check_random_number(v, argv);
|
||||
return v;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rand_random(int argc, VALUE *argv, VALUE obj, rb_random_t *rnd)
|
||||
rand_random(int argc, VALUE *argv, VALUE obj, const rb_random_interface_t *rng, rb_random_t *rnd)
|
||||
{
|
||||
VALUE vmax, v;
|
||||
|
||||
if (rb_check_arity(argc, 0, 1) == 0) {
|
||||
return rb_float_new(random_real(obj, rnd, TRUE));
|
||||
return rb_float_new(random_real(obj, rng, rnd, TRUE));
|
||||
}
|
||||
vmax = argv[0];
|
||||
if (NIL_P(vmax)) return Qnil;
|
||||
if (!RB_FLOAT_TYPE_P(vmax)) {
|
||||
v = rb_check_to_int(vmax);
|
||||
if (!NIL_P(v)) return rand_int(obj, rnd, v, 1);
|
||||
if (!NIL_P(v)) return rand_int(obj, rng, rnd, v, 1);
|
||||
}
|
||||
v = rb_check_to_float(vmax);
|
||||
if (!NIL_P(v)) {
|
||||
@ -1599,12 +1598,12 @@ rand_random(int argc, VALUE *argv, VALUE obj, rb_random_t *rnd)
|
||||
return Qnil;
|
||||
}
|
||||
else {
|
||||
double r = random_real(obj, rnd, TRUE);
|
||||
double r = random_real(obj, rng, rnd, TRUE);
|
||||
if (max > 0.0) r *= max;
|
||||
return rb_float_new(r);
|
||||
}
|
||||
}
|
||||
return rand_range(obj, rnd, vmax);
|
||||
return rand_range(obj, rng, rnd, vmax);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1622,9 +1621,10 @@ rand_random(int argc, VALUE *argv, VALUE obj, rb_random_t *rnd)
|
||||
static VALUE
|
||||
rand_random_number(int argc, VALUE *argv, VALUE obj)
|
||||
{
|
||||
rb_random_t *rnd = try_get_rnd(obj);
|
||||
VALUE v = rand_random(argc, argv, obj, rnd);
|
||||
if (NIL_P(v)) v = rand_random(0, 0, obj, rnd);
|
||||
const rb_random_interface_t *rng;
|
||||
rb_random_t *rnd = try_get_rnd(obj, &rng);
|
||||
VALUE v = rand_random(argc, argv, obj, rng, rnd);
|
||||
if (NIL_P(v)) v = rand_random(0, 0, obj, rng, rnd);
|
||||
else if (!v) invalid_argument(argv[0]);
|
||||
return v;
|
||||
}
|
||||
@ -1703,18 +1703,19 @@ static VALUE
|
||||
rb_f_rand(int argc, VALUE *argv, VALUE obj)
|
||||
{
|
||||
VALUE vmax;
|
||||
const rb_random_interface_t *rng = &random_mt_if;
|
||||
rb_random_t *rnd = default_rand_start();
|
||||
|
||||
if (rb_check_arity(argc, 0, 1) && !NIL_P(vmax = argv[0])) {
|
||||
VALUE v = rand_range(obj, rnd, vmax);
|
||||
VALUE v = rand_range(obj, rng, rnd, vmax);
|
||||
if (v != Qfalse) return v;
|
||||
vmax = rb_to_int(vmax);
|
||||
if (vmax != INT2FIX(0)) {
|
||||
v = rand_int(obj, rnd, vmax, 0);
|
||||
v = rand_int(obj, rng, rnd, vmax, 0);
|
||||
if (!NIL_P(v)) return v;
|
||||
}
|
||||
}
|
||||
return DBL2NUM(random_real(obj, rnd, TRUE));
|
||||
return DBL2NUM(random_real(obj, rng, rnd, TRUE));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1730,7 +1731,7 @@ rb_f_rand(int argc, VALUE *argv, VALUE obj)
|
||||
static VALUE
|
||||
random_s_rand(int argc, VALUE *argv, VALUE obj)
|
||||
{
|
||||
VALUE v = rand_random(argc, argv, Qnil, default_rand_start());
|
||||
VALUE v = rand_random(argc, argv, Qnil, &random_mt_if, default_rand_start());
|
||||
check_random_number(v, argv);
|
||||
return v;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user