diff options
| author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2025-12-28 13:49:02 +0900 |
|---|---|---|
| committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2025-12-29 02:01:12 +0900 |
| commit | 44e762a99c2234756594382f36fc64db1d6c31d0 (patch) | |
| tree | 879730eb014a1791874715e4084bb0c107ef5503 /random.c | |
| parent | 68cd46353c34cd87917930f80925b2ac8ddaaa9b (diff) | |
Extract `rb_random_interface_t` alongside `rb_random_t` as well
Diffstat (limited to 'random.c')
| -rw-r--r-- | random.c | 107 |
1 files changed, 54 insertions, 53 deletions
@@ -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; } |
